Moved MonoGame.Extended.Gui to its own repository (#905)

This commit is contained in:
Christopher Whitley
2024-06-29 18:28:12 -04:00
committed by GitHub
parent 1f3f1c5aa0
commit 98ee05f58a
59 changed files with 0 additions and 4339 deletions
-22
View File
@@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Entities", "so
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Graphics", "source\MonoGame.Extended.Graphics\FNA.Extended.Graphics.csproj", "{56627685-4BA7-44E3-ACA6-F2990DE089F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Gui", "source\MonoGame.Extended.Gui\FNA.Extended.Gui.csproj", "{16E79E22-A41A-47BC-9DC9-287B812A6DD1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Input", "source\MonoGame.Extended.Input\FNA.Extended.Input.csproj", "{76B39424-7884-4EEC-A8D5-5126B29941B7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Particles", "source\MonoGame.Extended.Particles\FNA.Extended.Particles.csproj", "{BE74938D-9004-4D36-AD50-5C6C141A7180}"
@@ -31,8 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Collisions.Tes
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Entities.Tests", "tests\MonoGame.Extended.Entities.Tests\FNA.Extended.Entities.Tests.csproj", "{D3B0E350-B92E-4E49-99A3-68E66CB53F16}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Gui.Tests", "tests\MonoGame.Extended.Gui.Tests\FNA.Extended.Gui.Tests.csproj", "{AA52F204-3EE7-40CB-B041-0AB36475DAF0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Tests", "tests\MonoGame.Extended.Tests\FNA.Extended.Tests.csproj", "{E1339B07-EB0B-454F-9803-E923843DB5C4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Extended.Tiled.Tests", "tests\MonoGame.Extended.Tiled.Tests\FNA.Extended.Tiled.Tests.csproj", "{BF0EC593-4BAB-424F-B7E9-BB13EC78A0E5}"
@@ -91,14 +87,6 @@ Global
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|Any CPU.Build.0 = Release|Any CPU
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|x86.ActiveCfg = Release|Any CPU
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|x86.Build.0 = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|x86.ActiveCfg = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|x86.Build.0 = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|Any CPU.Build.0 = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|x86.ActiveCfg = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|x86.Build.0 = Release|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -147,14 +135,6 @@ Global
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|Any CPU.Build.0 = Release|Any CPU
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|x86.ActiveCfg = Release|Any CPU
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|x86.Build.0 = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|x86.Build.0 = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|Any CPU.Build.0 = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|x86.ActiveCfg = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|x86.Build.0 = Release|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -197,14 +177,12 @@ Global
{7F60B59F-4B84-401F-8A13-AAA3F0B9E4A5} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{CD5C1878-13B6-4FAD-91AE-AEA3C1520E38} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{56627685-4BA7-44E3-ACA6-F2990DE089F2} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{16E79E22-A41A-47BC-9DC9-287B812A6DD1} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{76B39424-7884-4EEC-A8D5-5126B29941B7} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{BE74938D-9004-4D36-AD50-5C6C141A7180} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{572C908D-4627-4678-9641-D4950DE43B13} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{F144A062-4FF3-44EC-9A04-31C654B436B0} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{58F88A3C-C09F-4664-A34E-60E89252870A} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{D3B0E350-B92E-4E49-99A3-68E66CB53F16} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{AA52F204-3EE7-40CB-B041-0AB36475DAF0} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{E1339B07-EB0B-454F-9803-E923843DB5C4} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{BF0EC593-4BAB-424F-B7E9-BB13EC78A0E5} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{C2A9982B-7BF7-4243-9E05-CFD31752B6DC} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
-22
View File
@@ -17,8 +17,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Entities", "so
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Graphics", "source\MonoGame.Extended.Graphics\KNI.Extended.Graphics.csproj", "{56627685-4BA7-44E3-ACA6-F2990DE089F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Gui", "source\MonoGame.Extended.Gui\KNI.Extended.Gui.csproj", "{16E79E22-A41A-47BC-9DC9-287B812A6DD1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Input", "source\MonoGame.Extended.Input\KNI.Extended.Input.csproj", "{76B39424-7884-4EEC-A8D5-5126B29941B7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Particles", "source\MonoGame.Extended.Particles\KNI.Extended.Particles.csproj", "{BE74938D-9004-4D36-AD50-5C6C141A7180}"
@@ -37,8 +35,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Content.Pipeli
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Entities.Tests", "tests\MonoGame.Extended.Entities.Tests\KNI.Extended.Entities.Tests.csproj", "{D3B0E350-B92E-4E49-99A3-68E66CB53F16}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Gui.Tests", "tests\MonoGame.Extended.Gui.Tests\KNI.Extended.Gui.Tests.csproj", "{AA52F204-3EE7-40CB-B041-0AB36475DAF0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Tests", "tests\MonoGame.Extended.Tests\KNI.Extended.Tests.csproj", "{E1339B07-EB0B-454F-9803-E923843DB5C4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KNI.Extended.Tiled.Tests", "tests\MonoGame.Extended.Tiled.Tests\KNI.Extended.Tiled.Tests.csproj", "{BF0EC593-4BAB-424F-B7E9-BB13EC78A0E5}"
@@ -101,14 +97,6 @@ Global
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|Any CPU.Build.0 = Release|Any CPU
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|x86.ActiveCfg = Release|Any CPU
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|x86.Build.0 = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|x86.ActiveCfg = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|x86.Build.0 = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|Any CPU.Build.0 = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|x86.ActiveCfg = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|x86.Build.0 = Release|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -173,14 +161,6 @@ Global
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|Any CPU.Build.0 = Release|Any CPU
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|x86.ActiveCfg = Release|Any CPU
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|x86.Build.0 = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|x86.Build.0 = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|Any CPU.Build.0 = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|x86.ActiveCfg = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|x86.Build.0 = Release|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -216,7 +196,6 @@ Global
{4A4066EB-B49A-4E80-B424-9E0BD2147886} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{CD5C1878-13B6-4FAD-91AE-AEA3C1520E38} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{56627685-4BA7-44E3-ACA6-F2990DE089F2} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{16E79E22-A41A-47BC-9DC9-287B812A6DD1} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{76B39424-7884-4EEC-A8D5-5126B29941B7} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{BE74938D-9004-4D36-AD50-5C6C141A7180} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{572C908D-4627-4678-9641-D4950DE43B13} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
@@ -225,7 +204,6 @@ Global
{A127A61A-B26E-4A01-BD4C-9896FDB287AE} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{0426263A-B8DE-43FC-A91E-21544F61D80E} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{D3B0E350-B92E-4E49-99A3-68E66CB53F16} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{AA52F204-3EE7-40CB-B041-0AB36475DAF0} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{E1339B07-EB0B-454F-9803-E923843DB5C4} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{BF0EC593-4BAB-424F-B7E9-BB13EC78A0E5} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{C2A9982B-7BF7-4243-9E05-CFD31752B6DC} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
-22
View File
@@ -17,8 +17,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Entities"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Graphics", "source\MonoGame.Extended.Graphics\MonoGame.Extended.Graphics.csproj", "{56627685-4BA7-44E3-ACA6-F2990DE089F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Gui", "source\MonoGame.Extended.Gui\MonoGame.Extended.Gui.csproj", "{16E79E22-A41A-47BC-9DC9-287B812A6DD1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Input", "source\MonoGame.Extended.Input\MonoGame.Extended.Input.csproj", "{76B39424-7884-4EEC-A8D5-5126B29941B7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Particles", "source\MonoGame.Extended.Particles\MonoGame.Extended.Particles.csproj", "{BE74938D-9004-4D36-AD50-5C6C141A7180}"
@@ -37,8 +35,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Content.P
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Entities.Tests", "tests\MonoGame.Extended.Entities.Tests\MonoGame.Extended.Entities.Tests.csproj", "{D3B0E350-B92E-4E49-99A3-68E66CB53F16}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Gui.Tests", "tests\MonoGame.Extended.Gui.Tests\MonoGame.Extended.Gui.Tests.csproj", "{AA52F204-3EE7-40CB-B041-0AB36475DAF0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Tests", "tests\MonoGame.Extended.Tests\MonoGame.Extended.Tests.csproj", "{E1339B07-EB0B-454F-9803-E923843DB5C4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Tiled.Tests", "tests\MonoGame.Extended.Tiled.Tests\MonoGame.Extended.Tiled.Tests.csproj", "{BF0EC593-4BAB-424F-B7E9-BB13EC78A0E5}"
@@ -101,14 +97,6 @@ Global
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|Any CPU.Build.0 = Release|Any CPU
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|x86.ActiveCfg = Release|Any CPU
{56627685-4BA7-44E3-ACA6-F2990DE089F2}.Release|x86.Build.0 = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|x86.ActiveCfg = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Debug|x86.Build.0 = Debug|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|Any CPU.Build.0 = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|x86.ActiveCfg = Release|Any CPU
{16E79E22-A41A-47BC-9DC9-287B812A6DD1}.Release|x86.Build.0 = Release|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76B39424-7884-4EEC-A8D5-5126B29941B7}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -173,14 +161,6 @@ Global
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|Any CPU.Build.0 = Release|Any CPU
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|x86.ActiveCfg = Release|Any CPU
{D3B0E350-B92E-4E49-99A3-68E66CB53F16}.Release|x86.Build.0 = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Debug|x86.Build.0 = Debug|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|Any CPU.Build.0 = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|x86.ActiveCfg = Release|Any CPU
{AA52F204-3EE7-40CB-B041-0AB36475DAF0}.Release|x86.Build.0 = Release|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1339B07-EB0B-454F-9803-E923843DB5C4}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -216,7 +196,6 @@ Global
{4A4066EB-B49A-4E80-B424-9E0BD2147886} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{CD5C1878-13B6-4FAD-91AE-AEA3C1520E38} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{56627685-4BA7-44E3-ACA6-F2990DE089F2} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{16E79E22-A41A-47BC-9DC9-287B812A6DD1} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{76B39424-7884-4EEC-A8D5-5126B29941B7} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{BE74938D-9004-4D36-AD50-5C6C141A7180} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
{572C908D-4627-4678-9641-D4950DE43B13} = {2BD6F851-7287-4361-85AB-DAE9DF30D932}
@@ -225,7 +204,6 @@ Global
{A127A61A-B26E-4A01-BD4C-9896FDB287AE} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{0426263A-B8DE-43FC-A91E-21544F61D80E} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{D3B0E350-B92E-4E49-99A3-68E66CB53F16} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{AA52F204-3EE7-40CB-B041-0AB36475DAF0} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{E1339B07-EB0B-454F-9803-E923843DB5C4} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{BF0EC593-4BAB-424F-B7E9-BB13EC78A0E5} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
{C2A9982B-7BF7-4243-9E05-CFD31752B6DC} = {61C82014-E3A9-4AB3-8705-FBBD5F799BA6}
@@ -1,114 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MonoGame.Extended.Gui.Controls;
namespace MonoGame.Extended.Gui
{
public class ControlStyle : IDictionary<string, object>
{
private readonly Dictionary<Guid, Dictionary<string, object>> _previousStates = new Dictionary<Guid, Dictionary<string, object>>();
public ControlStyle()
: this(typeof(Element))
{
}
public ControlStyle(Type targetType)
: this(targetType.FullName, targetType)
{
}
public ControlStyle(string name, Type targetType)
{
Name = name;
TargetType = targetType;
_setters = new Dictionary<string, object>();
}
public string Name { get; }
public Type TargetType { get; set; }
private readonly Dictionary<string, object> _setters;
public void ApplyIf(Control control, bool predicate)
{
if (predicate)
Apply(control);
else
Revert(control);
}
public void Apply(Control control)
{
_previousStates[control.Id] = _setters
.ToDictionary(i => i.Key, i => TargetType.GetRuntimeProperty(i.Key)?.GetValue(control));
ChangePropertyValues(control, _setters);
}
public void Revert(Control control)
{
if (_previousStates.ContainsKey(control.Id) && _previousStates[control.Id] != null)
ChangePropertyValues(control, _previousStates[control.Id]);
_previousStates[control.Id] = null;
}
private static void ChangePropertyValues(Control control, Dictionary<string, object> setters)
{
var targetType = control.GetType();
foreach (var propertyName in setters.Keys)
{
var propertyInfo = targetType.GetRuntimeProperty(propertyName);
var value = setters[propertyName];
if (propertyInfo != null)
{
if(propertyInfo.CanWrite)
propertyInfo.SetValue(control, value);
// special case when we have a list of items as objects (like on a list box)
if (propertyInfo.PropertyType == typeof(List<object>))
{
var items = (List<object>)value;
var addMethod = propertyInfo.PropertyType.GetRuntimeMethod("Add", new[] { typeof(object) });
foreach (var item in items)
addMethod.Invoke(propertyInfo.GetValue(control), new[] {item});
}
}
}
}
public object this[string key]
{
get { return _setters[key]; }
set { _setters[key] = value; }
}
public ICollection<string> Keys => _setters.Keys;
public ICollection<object> Values => _setters.Values;
public int Count => _setters.Count;
public bool IsReadOnly => false;
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => _setters.GetEnumerator();
public void Add(string key, object value) => _setters.Add(key, value);
public void Add(KeyValuePair<string, object> item) => _setters.Add(item.Key, item.Value);
public bool Remove(string key) => _setters.Remove(key);
public bool Remove(KeyValuePair<string, object> item) => _setters.Remove(item.Key);
public void Clear() => _setters.Clear();
public bool Contains(KeyValuePair<string, object> item) => _setters.Contains(item);
public bool ContainsKey(string key) => _setters.ContainsKey(key);
public bool TryGetValue(string key, out object value) => _setters.TryGetValue(key, out value);
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
throw new NotSupportedException();
}
}
}
@@ -1,24 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public class Box : Control
{
public override IEnumerable<Control> Children { get; } = Enumerable.Empty<Control>();
public override Size GetContentSize(IGuiContext context)
{
return new Size(Width, Height);
}
public Color FillColor { get; set; } = Color.White;
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
renderer.FillRectangle(ContentRectangle, FillColor);
}
}
}
@@ -1,92 +0,0 @@
using System;
namespace MonoGame.Extended.Gui.Controls
{
public class Button : ContentControl
{
public Button()
{
}
public event EventHandler Clicked;
public event EventHandler PressedStateChanged;
private bool _isPressed;
public bool IsPressed
{
get => _isPressed;
set
{
if (_isPressed != value)
{
_isPressed = value;
PressedStyle?.ApplyIf(this, _isPressed);
PressedStateChanged?.Invoke(this, EventArgs.Empty);
}
}
}
private ControlStyle _pressedStyle;
public ControlStyle PressedStyle
{
get => _pressedStyle;
set
{
if (_pressedStyle != value)
{
_pressedStyle = value;
PressedStyle?.ApplyIf(this, _isPressed);
}
}
}
private bool _isPointerDown;
public override bool OnPointerDown(IGuiContext context, PointerEventArgs args)
{
if (IsEnabled)
{
_isPointerDown = true;
IsPressed = true;
}
return base.OnPointerDown(context, args);
}
public override bool OnPointerUp(IGuiContext context, PointerEventArgs args)
{
_isPointerDown = false;
if (IsPressed)
{
IsPressed = false;
if (BoundingRectangle.Contains(args.Position) && IsEnabled)
Click();
}
return base.OnPointerUp(context, args);
}
public override bool OnPointerEnter(IGuiContext context, PointerEventArgs args)
{
if (IsEnabled && _isPointerDown)
IsPressed = true;
return base.OnPointerEnter(context, args);
}
public override bool OnPointerLeave(IGuiContext context, PointerEventArgs args)
{
if (IsEnabled)
IsPressed = false;
return base.OnPointerLeave(context, args);
}
public void Click()
{
Clicked?.Invoke(this, EventArgs.Empty);
}
}
}
@@ -1,25 +0,0 @@
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public class Canvas : LayoutControl
{
public Canvas()
{
}
protected override void Layout(IGuiContext context, Rectangle rectangle)
{
foreach (var control in Items)
{
var actualSize = control.CalculateActualSize(context);
PlaceControl(context, control, control.Position.X, control.Position.Y, actualSize.Width, actualSize.Height);
}
}
public override Size GetContentSize(IGuiContext context)
{
return new Size();
}
}
}
@@ -1,65 +0,0 @@
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public class CheckBox : CompositeControl
{
public CheckBox()
{
_contentLabel = new Label();
_checkLabel = new Box {Width = 20, Height = 20};
_toggleButton = new ToggleButton
{
Margin = 0,
Padding = 0,
BackgroundColor = Color.Transparent,
BorderThickness = 0,
HoverStyle = null,
CheckedStyle = null,
PressedStyle = null,
Content = new StackPanel
{
Margin = 0,
Orientation = Orientation.Horizontal,
Items =
{
_checkLabel,
_contentLabel
}
}
};
_toggleButton.CheckedStateChanged += (sender, args) => OnIsCheckedChanged();
Template = _toggleButton;
OnIsCheckedChanged();
}
private readonly Label _contentLabel;
private readonly ToggleButton _toggleButton;
private readonly Box _checkLabel;
protected override Control Template { get; }
public override object Content
{
get => _contentLabel.Content;
set => _contentLabel.Content = value;
}
public bool IsChecked
{
get => _toggleButton.IsChecked;
set
{
_toggleButton.IsChecked = value;
OnIsCheckedChanged();
}
}
private void OnIsCheckedChanged()
{
_checkLabel.FillColor = IsChecked ? Color.White : Color.Transparent;
}
}
}
@@ -1,102 +0,0 @@
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended.Graphics;
using MonoGame.Extended.Input.InputListeners;
namespace MonoGame.Extended.Gui.Controls
{
public class ComboBox : SelectorControl
{
public ComboBox()
{
}
public bool IsOpen { get; set; }
public Texture2DRegion DropDownRegion { get; set; }
public Color DropDownColor { get; set; } = Color.White;
public override bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args)
{
if (args.Key == Keys.Enter)
IsOpen = false;
return base.OnKeyPressed(context, args);
}
public override bool OnPointerUp(IGuiContext context, PointerEventArgs args)
{
IsOpen = !IsOpen;
return base.OnPointerUp(context, args);
}
protected override Rectangle GetListAreaRectangle(IGuiContext context)
{
return GetDropDownRectangle(context);
}
public override bool Contains(IGuiContext context, Point point)
{
return base.Contains(context, point) || IsOpen && GetListAreaRectangle(context).Contains(point);
}
public override Size GetContentSize(IGuiContext context)
{
var width = 0;
var height = 0;
foreach (var item in Items)
{
var itemSize = GetItemSize(context, item);
if (itemSize.Width > width)
width = itemSize.Width;
if (itemSize.Height > height)
height = itemSize.Height;
}
return new Size(width + ClipPadding.Width, height + ClipPadding.Height);
}
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
if (IsOpen)
{
var dropDownRectangle = GetListAreaRectangle(context);
if (DropDownRegion != null)
{
renderer.DrawRegion(DropDownRegion, dropDownRectangle, DropDownColor);
}
else
{
renderer.FillRectangle(dropDownRectangle, DropDownColor);
renderer.DrawRectangle(dropDownRectangle, BorderColor);
}
DrawItemList(context, renderer);
}
var selectedTextInfo = GetItemTextInfo(context, ContentRectangle, SelectedItem);
if (!string.IsNullOrWhiteSpace(selectedTextInfo.Text))
renderer.DrawText(selectedTextInfo.Font, selectedTextInfo.Text, selectedTextInfo.Position + TextOffset, selectedTextInfo.Color, selectedTextInfo.ClippingRectangle);
}
private Rectangle GetDropDownRectangle(IGuiContext context)
{
var dropDownRectangle = BoundingRectangle;
dropDownRectangle.Y = dropDownRectangle.Y + dropDownRectangle.Height;
dropDownRectangle.Height = (int) Items
.Select(item => GetItemSize(context, item))
.Select(itemSize => itemSize.Height)
.Sum();
return dropDownRectangle;
}
}
}
@@ -1,70 +0,0 @@
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public abstract class CompositeControl : Control
{
protected CompositeControl()
{
}
protected bool IsDirty { get; set; } = true;
public abstract object Content { get; set; }
protected abstract Control Template { get; }
public override IEnumerable<Control> Children
{
get
{
var control = Template;
if (control != null)
yield return control;
}
}
public override void InvalidateMeasure()
{
base.InvalidateMeasure();
IsDirty = true;
}
public override Size GetContentSize(IGuiContext context)
{
var control = Template;
if (control != null)
return Template.CalculateActualSize(context);
return Size.Empty;
}
public override void Update(IGuiContext context, float deltaSeconds)
{
var control = Template;
if (control != null)
{
if (IsDirty)
{
control.Parent = this;
control.ActualSize = new Point(ContentRectangle.Width, ContentRectangle.Height);
control.Position = new Point(Padding.Left, Padding.Top);
control.InvalidateMeasure();
IsDirty = false;
}
}
}
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
var control = Template;
control?.Draw(context, renderer, deltaSeconds);
}
}
}
@@ -1,82 +0,0 @@
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public class ContentControl : Control
{
private bool _contentChanged = true;
private object _content;
public object Content
{
get => _content;
set
{
if (_content != value)
{
_content = value;
_contentChanged = true;
}
}
}
public override IEnumerable<Control> Children
{
get
{
if (Content is Control control)
yield return control;
}
}
public bool HasContent => Content == null;
public override void InvalidateMeasure()
{
base.InvalidateMeasure();
_contentChanged = true;
}
public override void Update(IGuiContext context, float deltaSeconds)
{
if (_content is Control control && _contentChanged)
{
control.Parent = this;
control.ActualSize = new Point(ContentRectangle.Width, ContentRectangle.Height);
control.Position = new Point(Padding.Left, Padding.Top);
control.InvalidateMeasure();
_contentChanged = false;
}
}
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
if (Content is Control control)
{
control.Draw(context, renderer, deltaSeconds);
}
else
{
var text = Content?.ToString();
var textInfo = GetTextInfo(context, text, ContentRectangle, HorizontalTextAlignment, VerticalTextAlignment);
if (!string.IsNullOrWhiteSpace(textInfo.Text))
renderer.DrawText(textInfo.Font, textInfo.Text, textInfo.Position + TextOffset, textInfo.Color, textInfo.ClippingRectangle);
}
}
public override Size GetContentSize(IGuiContext context)
{
if (Content is Control control)
return control.CalculateActualSize(context);
var text = Content?.ToString();
var font = Font ?? context.DefaultFont;
return (Size)font.MeasureString(text ?? string.Empty);
}
}
}
@@ -1,271 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Microsoft.Xna.Framework;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Input.InputListeners;
namespace MonoGame.Extended.Gui.Controls
{
public abstract class Control : Element<Control>, IRectangular
{
protected Control()
{
BackgroundColor = Color.White;
TextColor = Color.White;
IsEnabled = true;
IsVisible = true;
Origin = Point.Zero;
Skin = Skin.Default;
}
private Skin _skin;
[EditorBrowsable(EditorBrowsableState.Never)]
public Skin Skin
{
get => _skin;
set
{
if (_skin != value)
{
_skin = value;
_skin?.Apply(this);
}
}
}
public abstract IEnumerable<Control> Children { get; }
[EditorBrowsable(EditorBrowsableState.Never)]
public Thickness Margin { get; set; }
[EditorBrowsable(EditorBrowsableState.Never)]
public Thickness Padding { get; set; }
[EditorBrowsable(EditorBrowsableState.Never)]
public Thickness ClipPadding { get; set; }
public bool IsLayoutRequired { get; set; }
public Rectangle ClippingRectangle
{
get
{
var r = BoundingRectangle;
return new Rectangle(r.Left + ClipPadding.Left, r.Top + ClipPadding.Top, r.Width - ClipPadding.Width, r.Height - ClipPadding.Height);
}
}
public Rectangle ContentRectangle
{
get
{
var r = BoundingRectangle;
return new Rectangle(r.Left + Padding.Left, r.Top + Padding.Top, r.Width - Padding.Width, r.Height - Padding.Height);
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsFocused { get; set; }
private bool _isHovered;
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsHovered
{
get => _isHovered;
private set
{
if (_isHovered != value)
{
_isHovered = value;
HoverStyle?.ApplyIf(this, _isHovered);
}
}
}
[JsonIgnore]
[EditorBrowsable(EditorBrowsableState.Never)]
public Guid Id { get; set; } = Guid.NewGuid();
public Vector2 Offset { get; set; }
public BitmapFont Font { get; set; }
public Color TextColor { get; set; }
public Vector2 TextOffset { get; set; }
public HorizontalAlignment HorizontalAlignment { get; set; } = HorizontalAlignment.Stretch;
public VerticalAlignment VerticalAlignment { get; set; } = VerticalAlignment.Stretch;
public HorizontalAlignment HorizontalTextAlignment { get; set; } = HorizontalAlignment.Centre;
public VerticalAlignment VerticalTextAlignment { get; set; } = VerticalAlignment.Centre;
public abstract Size GetContentSize(IGuiContext context);
public virtual Size CalculateActualSize(IGuiContext context)
{
var fixedSize = Size;
var desiredSize = GetContentSize(context) + Margin.Size + Padding.Size;
if (desiredSize.Width < MinWidth)
desiredSize.Width = MinWidth;
if (desiredSize.Height < MinHeight)
desiredSize.Height = MinHeight;
if (desiredSize.Width > MaxWidth)
desiredSize.Width = MaxWidth;
if (desiredSize.Height > MaxWidth)
desiredSize.Height = MaxHeight;
var width = fixedSize.Width == 0 ? desiredSize.Width : fixedSize.Width;
var height = fixedSize.Height == 0 ? desiredSize.Height : fixedSize.Height;
return new Size(width, height);
}
public virtual void InvalidateMeasure() { }
private bool _isEnabled;
public bool IsEnabled
{
get => _isEnabled;
set
{
if (_isEnabled != value)
{
_isEnabled = value;
DisabledStyle?.ApplyIf(this, !_isEnabled);
}
}
}
public bool IsVisible { get; set; }
private ControlStyle _hoverStyle;
public ControlStyle HoverStyle
{
get => _hoverStyle;
set
{
if (_hoverStyle != value)
{
_hoverStyle = value;
HoverStyle?.ApplyIf(this, _isHovered);
}
}
}
private ControlStyle _disabledStyle;
public ControlStyle DisabledStyle
{
get => _disabledStyle;
set
{
_disabledStyle = value;
DisabledStyle?.ApplyIf(this, !_isEnabled);
}
}
public virtual void OnScrolled(int delta) { }
public virtual bool OnKeyTyped(IGuiContext context, KeyboardEventArgs args) { return true; }
public virtual bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args) { return true; }
public virtual bool OnFocus(IGuiContext context) { return true; }
public virtual bool OnUnfocus(IGuiContext context) { return true; }
public virtual bool OnPointerDown(IGuiContext context, PointerEventArgs args) { return true; }
public virtual bool OnPointerMove(IGuiContext context, PointerEventArgs args) { return true; }
public virtual bool OnPointerUp(IGuiContext context, PointerEventArgs args) { return true; }
public virtual bool OnPointerEnter(IGuiContext context, PointerEventArgs args)
{
if (IsEnabled && !IsHovered)
IsHovered = true;
return true;
}
public virtual bool OnPointerLeave(IGuiContext context, PointerEventArgs args)
{
if (IsEnabled && IsHovered)
IsHovered = false;
return true;
}
public virtual bool Contains(IGuiContext context, Point point)
{
return BoundingRectangle.Contains(point);
}
public virtual void Update(IGuiContext context, float deltaSeconds) { }
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
if (BackgroundRegion != null)
renderer.DrawRegion(BackgroundRegion, BoundingRectangle, BackgroundColor);
else if (BackgroundColor != Color.Transparent)
renderer.FillRectangle(BoundingRectangle, BackgroundColor);
if (BorderThickness != 0)
renderer.DrawRectangle(BoundingRectangle, BorderColor, BorderThickness);
// handy debug rectangles
//renderer.DrawRectangle(ContentRectangle, Color.Magenta);
//renderer.DrawRectangle(BoundingRectangle, Color.Lime);
}
public bool HasParent(Control control)
{
return Parent != null && (Parent == control || Parent.HasParent(control));
}
protected TextInfo GetTextInfo(IGuiContext context, string text, Rectangle targetRectangle, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment)
{
var font = Font ?? context.DefaultFont;
var textSize = (Size)font.GetStringRectangle(text ?? string.Empty, Vector2.Zero).Size;
var destinationRectangle = LayoutHelper.AlignRectangle(horizontalAlignment, verticalAlignment, textSize, targetRectangle);
var textPosition = destinationRectangle.Location.ToVector2();
var textInfo = new TextInfo(text, font, textPosition, textSize, TextColor, targetRectangle);
return textInfo;
}
public struct TextInfo
{
public TextInfo(string text, BitmapFont font, Vector2 position, Size size, Color color, Rectangle? clippingRectangle)
{
Text = text ?? string.Empty;
Font = font;
Size = size;
Color = color;
ClippingRectangle = clippingRectangle;
Position = position;
}
public string Text;
public BitmapFont Font;
public Size Size;
public Color Color;
public Rectangle? ClippingRectangle;
public Vector2 Position;
}
public Dictionary<string, object> AttachedProperties { get; } = new Dictionary<string, object>();
public object GetAttachedProperty(string name)
{
return AttachedProperties.TryGetValue(name, out var value) ? value : null;
}
public void SetAttachedProperty(string name, object value)
{
AttachedProperties[name] = value;
}
public virtual Type GetAttachedPropertyType(string propertyName)
{
return null;
}
}
}
@@ -1,15 +0,0 @@
namespace MonoGame.Extended.Gui.Controls
{
public class ControlCollection : ElementCollection<Control, Control>
{
public ControlCollection()
: base(null)
{
}
public ControlCollection(Control parent)
: base(parent)
{
}
}
}
@@ -1,41 +0,0 @@
using System.Linq;
namespace MonoGame.Extended.Gui.Controls
{
//public class Dialog : LayoutControl
//{
// public Dialog()
// {
// HorizontalAlignment = HorizontalAlignment.Centre;
// VerticalAlignment = VerticalAlignment.Centre;
// }
// public Thickness Padding { get; set; }
// public Screen Owner { get; private set; }
// public void Show(Screen owner)
// {
// Owner = owner;
// Owner.Controls.Add(this);
// }
// public void Hide()
// {
// Owner.Controls.Remove(this);
// }
// protected override Size2 CalculateDesiredSize(IGuiContext context, Size2 availableSize)
// {
// var sizes = Items.Select(control => LayoutHelper.GetSizeWithMargins(control, context, availableSize)).ToArray();
// var width = sizes.Max(s => s.Width);
// var height = sizes.Max(s => s.Height);
// return new Size2(width, height) + Padding.Size;
// }
// public override void Layout(IGuiContext context, RectangleF rectangle)
// {
// foreach (var control in Items)
// PlaceControl(context, control, Padding.Left, Padding.Top, Width - Padding.Size.Width, Height - Padding.Size.Height);
// }
//}
}
@@ -1,104 +0,0 @@
using System;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public enum Dock
{
Left, Right, Top, Bottom
}
public class DockPanel : LayoutControl
{
public override Size GetContentSize(IGuiContext context)
{
var size = new Size();
for (var i = 0; i < Items.Count; i++)
{
var control = Items[i];
var actualSize = control.CalculateActualSize(context);
if (LastChildFill && i == Items.Count - 1)
{
size.Width += actualSize.Width;
size.Height += actualSize.Height;
}
else
{
var dock = control.GetAttachedProperty(DockProperty) as Dock? ?? Dock.Left;
switch (dock)
{
case Dock.Left:
case Dock.Right:
size.Width += actualSize.Width;
break;
case Dock.Top:
case Dock.Bottom:
size.Height += actualSize.Height;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
return size;
}
protected override void Layout(IGuiContext context, Rectangle rectangle)
{
for (var i = 0; i < Items.Count; i++)
{
var control = Items[i];
if (LastChildFill && i == Items.Count - 1)
{
PlaceControl(context, control, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
else
{
var actualSize = control.CalculateActualSize(context);
var dock = control.GetAttachedProperty(DockProperty) as Dock? ?? Dock.Left;
switch (dock)
{
case Dock.Left:
PlaceControl(context, control, rectangle.Left, rectangle.Top, actualSize.Width, rectangle.Height);
rectangle.X += actualSize.Width;
rectangle.Width -= actualSize.Width;
break;
case Dock.Right:
PlaceControl(context, control, rectangle.Right - actualSize.Width, rectangle.Top, actualSize.Width, rectangle.Height);
rectangle.Width -= actualSize.Width;
break;
case Dock.Top:
PlaceControl(context, control, rectangle.Left, rectangle.Top, rectangle.Width, actualSize.Height);
rectangle.Y += actualSize.Height;
rectangle.Height -= actualSize.Height;
break;
case Dock.Bottom:
PlaceControl(context, control, rectangle.Left, rectangle.Bottom - actualSize.Height, rectangle.Width, actualSize.Height);
rectangle.Height -= actualSize.Height;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
public const string DockProperty = "Dock";
public override Type GetAttachedPropertyType(string propertyName)
{
if (string.Equals(DockProperty, propertyName, StringComparison.OrdinalIgnoreCase))
return typeof(Dock);
return base.GetAttachedPropertyType(propertyName);
}
public bool LastChildFill { get; set; } = true;
}
}
@@ -1,42 +0,0 @@
using System.Linq;
using MonoGame.Extended.Input.InputListeners;
using Microsoft.Xna.Framework.Input;
namespace MonoGame.Extended.Gui.Controls
{
//public class Form : StackPanel
//{
// public Form()
// {
// }
// public override bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args)
// {
// if (args.Key == Keys.Tab)
// {
// var controls = FindControls<Control>();
// var index = controls.IndexOf(context.FocusedControl);
// if (index > -1)
// {
// index++;
// if (index >= controls.Count) index = 0;
// context.SetFocus(controls[index]);
// return true;
// }
// }
// if (args.Key == Keys.Enter)
// {
// var controls = FindControls<Submit>();
// if (controls.Count > 0)
// {
// var submit = controls.FirstOrDefault();
// submit.TriggerClicked();
// return true;
// }
// }
// return base.OnKeyPressed(context, args);
// }
//}
}
@@ -1,60 +0,0 @@
using System.Collections.Generic;
namespace MonoGame.Extended.Gui.Controls
{
public abstract class ItemsControl : Control
{
protected ItemsControl()
{
Items = new ControlCollection(this);
//{
// ItemAdded = x => UpdateRootIsLayoutRequired(),
// ItemRemoved = x => UpdateRootIsLayoutRequired()
//};
}
public override IEnumerable<Control> Children => Items;
public ControlCollection Items { get; }
///// <summary>
///// Recursive Method to find the root element and update the IsLayoutRequired property. So that the screen knows that something in the controls
///// have had a change to their layout. Also, it will reset the size of the element so that it can get a clean build so that the background patches
///// can be rendered with the updates.
///// </summary>
//private void UpdateRootIsLayoutRequired()
//{
// var parent = Parent as ItemsControl;
// if (parent == null)
// IsLayoutRequired = true;
// else
// parent.UpdateRootIsLayoutRequired();
// Size = Size2.Empty;
//}
//protected List<T> FindControls<T>()
// where T : Control
//{
// return FindControls<T>(Items);
//}
//protected List<T> FindControls<T>(ControlCollection controls)
// where T : Control
//{
// var results = new List<T>();
// foreach (var control in controls)
// {
// if (control is T)
// results.Add(control as T);
// var itemsControl = control as ItemsControl;
// if (itemsControl != null && itemsControl.Items.Any())
// results = results.Concat(FindControls<T>(itemsControl.Items)).ToList();
// }
// return results;
//}
}
}
@@ -1,14 +0,0 @@
namespace MonoGame.Extended.Gui.Controls
{
public class Label : ContentControl
{
public Label()
{
}
public Label(string text = null)
{
Content = text ?? string.Empty;
}
}
}
@@ -1,40 +0,0 @@
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public abstract class LayoutControl : ItemsControl
{
protected LayoutControl()
{
HorizontalAlignment = HorizontalAlignment.Stretch;
VerticalAlignment = VerticalAlignment.Stretch;
BackgroundColor = Color.Transparent;
}
private bool _isLayoutValid;
public override void InvalidateMeasure()
{
base.InvalidateMeasure();
_isLayoutValid = false;
}
public override void Update(IGuiContext context, float deltaSeconds)
{
base.Update(context, deltaSeconds);
if (!_isLayoutValid)
{
Layout(context, new Rectangle(Padding.Left, Padding.Top, ContentRectangle.Width, ContentRectangle.Height));
_isLayoutValid = true;
}
}
protected abstract void Layout(IGuiContext context, Rectangle rectangle);
protected static void PlaceControl(IGuiContext context, Control control, float x, float y, float width, float height)
{
LayoutHelper.PlaceControl(context, control, x, y, width, height);
}
}
}
@@ -1,42 +0,0 @@
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public class ListBox : SelectorControl
{
public ListBox()
{
}
public override Size GetContentSize(IGuiContext context)
{
var width = 0;
var height = 0;
foreach (var item in Items)
{
var itemSize = GetItemSize(context, item);
if (itemSize.Width > width)
width = itemSize.Width;
height += itemSize.Height;
}
return new Size(width + ClipPadding.Width, height + ClipPadding.Height);
}
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
ScrollIntoView(context);
DrawItemList(context, renderer);
}
protected override Rectangle GetListAreaRectangle(IGuiContext context)
{
return ContentRectangle;
}
}
}
@@ -1,62 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Graphics;
namespace MonoGame.Extended.Gui.Controls
{
public class ProgressBar : Control
{
public ProgressBar()
{
}
private float _progress = 1.0f;
public float Progress
{
get { return _progress; }
set
{
// ReSharper disable once CompareOfFloatsByEqualityOperator
if(_progress != value)
{
_progress = value;
ProgressChanged?.Invoke(this, EventArgs.Empty);
}
}
}
public Texture2DRegion BarRegion { get; set; }
public Color BarColor { get; set; } = Color.White;
public event EventHandler ProgressChanged;
public override IEnumerable<Control> Children { get; } = Enumerable.Empty<Control>();
public override Size GetContentSize(IGuiContext context)
{
return new Size(5, 5);
}
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
var boundingRectangle = ContentRectangle;
var clippingRectangle = new Rectangle(boundingRectangle.X, boundingRectangle.Y, (int)(boundingRectangle.Width * Progress), boundingRectangle.Height);
if (BarRegion != null)
renderer.DrawRegion(BarRegion, BoundingRectangle, BarColor, clippingRectangle);
else
renderer.FillRectangle(BoundingRectangle, BarColor, clippingRectangle);
}
//protected override void DrawBackground(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
//{
// base.DrawBackground(context, renderer, deltaSeconds);
//}
}
}
@@ -1,173 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended.Input.InputListeners;
namespace MonoGame.Extended.Gui.Controls
{
public abstract class SelectorControl : Control
{
protected SelectorControl()
{
}
private int _selectedIndex = -1;
public virtual int SelectedIndex
{
get { return _selectedIndex; }
set
{
if (_selectedIndex != value)
{
_selectedIndex = value;
SelectedIndexChanged?.Invoke(this, EventArgs.Empty);
}
}
}
public override IEnumerable<Control> Children => Items.OfType<Control>();
public virtual List<object> Items { get; } = new List<object>();
public virtual Color SelectedTextColor { get; set; } = Color.White;
public virtual Color SelectedItemColor { get; set; } = Color.CornflowerBlue;
public virtual Thickness ItemPadding { get; set; } = new Thickness(4, 2);
public virtual string NameProperty { get; set; }
public event EventHandler SelectedIndexChanged;
protected int FirstIndex;
public object SelectedItem
{
get { return SelectedIndex >= 0 && SelectedIndex <= Items.Count - 1 ? Items[SelectedIndex] : null; }
set { SelectedIndex = Items.IndexOf(value); }
}
public override bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args)
{
if (args.Key == Keys.Down) ScrollDown();
if (args.Key == Keys.Up) ScrollUp();
return base.OnKeyPressed(context, args);
}
public override void OnScrolled(int delta)
{
base.OnScrolled(delta);
if (delta < 0) ScrollDown();
if (delta > 0) ScrollUp();
}
private void ScrollDown()
{
if (SelectedIndex < Items.Count - 1)
SelectedIndex++;
}
private void ScrollUp()
{
if (SelectedIndex > 0)
SelectedIndex--;
}
public override bool OnPointerDown(IGuiContext context, PointerEventArgs args)
{
var contentRectangle = GetListAreaRectangle(context);
for (var i = FirstIndex; i < Items.Count; i++)
{
var itemRectangle = GetItemRectangle(context, i - FirstIndex, contentRectangle);
if (itemRectangle.Contains(args.Position))
{
SelectedIndex = i;
OnItemClicked(context, args);
break;
}
}
return base.OnPointerDown(context, args);
}
protected virtual void OnItemClicked(IGuiContext context, PointerEventArgs args) { }
protected TextInfo GetItemTextInfo(IGuiContext context, Rectangle itemRectangle, object item)
{
var textRectangle = new Rectangle(itemRectangle.X + ItemPadding.Left, itemRectangle.Y + ItemPadding.Top,
itemRectangle.Width - ItemPadding.Right, itemRectangle.Height - ItemPadding.Bottom);
var itemTextInfo = GetTextInfo(context, GetItemName(item), textRectangle, HorizontalTextAlignment, VerticalTextAlignment);
return itemTextInfo;
}
private string GetItemName(object item)
{
if (item != null)
{
if (NameProperty != null)
{
return item.GetType()
.GetRuntimeProperty(NameProperty)
.GetValue(item)
?.ToString() ?? string.Empty;
}
return item.ToString();
}
return string.Empty;
}
protected Rectangle GetItemRectangle(IGuiContext context, int index, Rectangle contentRectangle)
{
var font = Font ?? context.DefaultFont;
var itemHeight = font.LineHeight + ItemPadding.Top + ItemPadding.Bottom;
return new Rectangle(contentRectangle.X, contentRectangle.Y + itemHeight * index, contentRectangle.Width, itemHeight);
}
protected void ScrollIntoView(IGuiContext context)
{
var contentRectangle = GetListAreaRectangle(context);
var selectedItemRectangle = GetItemRectangle(context, SelectedIndex - FirstIndex, contentRectangle);
if (selectedItemRectangle.Bottom > ClippingRectangle.Bottom)
FirstIndex++;
if (selectedItemRectangle.Top < ClippingRectangle.Top && FirstIndex > 0)
FirstIndex--;
}
protected Size GetItemSize(IGuiContext context, object item)
{
var text = GetItemName(item);
var font = Font ?? context.DefaultFont;
var textSize = (Size)font.MeasureString(text ?? string.Empty);
var itemWidth = textSize.Width + ItemPadding.Width;
var itemHeight = textSize.Height + ItemPadding.Height;
return new Size(itemWidth, itemHeight);
}
protected abstract Rectangle GetListAreaRectangle(IGuiContext context);
protected void DrawItemList(IGuiContext context, IGuiRenderer renderer)
{
var listRectangle = GetListAreaRectangle(context);
for (var i = FirstIndex; i < Items.Count; i++)
{
var item = Items[i];
var itemRectangle = GetItemRectangle(context, i - FirstIndex, listRectangle);
var itemTextInfo = GetItemTextInfo(context, itemRectangle, item);
var textColor = i == SelectedIndex ? SelectedTextColor : itemTextInfo.Color;
if (SelectedIndex == i)
renderer.FillRectangle(itemRectangle, SelectedItemColor, listRectangle);
renderer.DrawText(itemTextInfo.Font, itemTextInfo.Text, itemTextInfo.Position + TextOffset, textColor, itemTextInfo.ClippingRectangle);
}
}
}
}
@@ -1,69 +0,0 @@
using System;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public class StackPanel : LayoutControl
{
public StackPanel()
{
}
public Orientation Orientation { get; set; } = Orientation.Vertical;
public int Spacing { get; set; }
public override Size GetContentSize(IGuiContext context)
{
var width = 0;
var height = 0;
foreach (var control in Items)
{
var actualSize = control.CalculateActualSize(context);
switch (Orientation)
{
case Orientation.Horizontal:
width += actualSize.Width;
height = actualSize.Height > height ? actualSize.Height : height;
break;
case Orientation.Vertical:
width = actualSize.Width > width ? actualSize.Width : width;
height += actualSize.Height;
break;
default:
throw new InvalidOperationException($"Unexpected orientation {Orientation}");
}
}
width += Orientation == Orientation.Horizontal ? (Items.Count - 1) * Spacing : 0;
height += Orientation == Orientation.Vertical ? (Items.Count - 1) * Spacing : 0;
return new Size(width, height);
}
protected override void Layout(IGuiContext context, Rectangle rectangle)
{
foreach (var control in Items)
{
var actualSize = control.CalculateActualSize(context);
switch (Orientation)
{
case Orientation.Vertical:
PlaceControl(context, control, rectangle.X, rectangle.Y, rectangle.Width, actualSize.Height);
rectangle.Y += actualSize.Height + Spacing;
rectangle.Height -= actualSize.Height;
break;
case Orientation.Horizontal:
PlaceControl(context, control, rectangle.X, rectangle.Y, actualSize.Width, rectangle.Height);
rectangle.X += actualSize.Width + Spacing;
rectangle.Width -= actualSize.Width;
break;
default:
throw new InvalidOperationException($"Unexpected orientation {Orientation}");
}
}
}
}
}
@@ -1,331 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended.Input.InputListeners;
namespace MonoGame.Extended.Gui.Controls
{
public sealed class TextBox : Control
{
public TextBox(string text = null)
{
Text = text ?? string.Empty;
HorizontalTextAlignment = HorizontalAlignment.Left;
}
public TextBox()
: this(null)
{
}
public int SelectionStart { get; set; }
public char? PasswordCharacter { get; set; }
private string _text;
public string Text
{
get { return _text; }
set
{
if (_text != value)
{
_text = value;
OnTextChanged();
}
}
}
private void OnTextChanged()
{
if (!string.IsNullOrEmpty(Text) && SelectionStart > Text.Length)
SelectionStart = Text.Length;
TextChanged?.Invoke(this, EventArgs.Empty);
}
public event EventHandler TextChanged;
public override IEnumerable<Control> Children { get; } = Enumerable.Empty<Control>();
public override Size GetContentSize(IGuiContext context)
{
var font = Font ?? context.DefaultFont;
var stringSize = (Size) font.MeasureString(Text ?? string.Empty);
return new Size(stringSize.Width,
stringSize.Height < font.LineHeight ? font.LineHeight : stringSize.Height);
}
//protected override Size2 CalculateDesiredSize(IGuiContext context, Size2 availableSize)
//{
// var font = Font ?? context.DefaultFont;
// return new Size2(Width + Padding.Left + Padding.Right, (Height <= 0.0f ? font.LineHeight + 2 : Height) + Padding.Top + Padding.Bottom);
//}
public override bool OnPointerDown(IGuiContext context, PointerEventArgs args)
{
SelectionStart = FindNearestGlyphIndex(context, args.Position);
_isCaretVisible = true;
//_selectionIndexes.Clear();
//_selectionIndexes.Push(SelectionStart);
//_startSelectionBox = Text.Length > 0;
return base.OnPointerDown(context, args);
}
//public override bool OnPointerMove(IGuiContext context, PointerEventArgs args)
//{
// if (_startSelectionBox)
// {
// var selection = FindNearestGlyphIndex(context, args.Position);
// if (selection != _selectionIndexes.Peek())
// {
// if (_selectionIndexes.Count == 1)
// {
// _selectionIndexes.Push(selection);
// }
// else if (_selectionIndexes.Last() < _selectionIndexes.Peek())
// {
// if (selection > _selectionIndexes.Peek()) _selectionIndexes.Pop();
// else _selectionIndexes.Push(selection);
// }
// else
// {
// if (selection < _selectionIndexes.Peek()) _selectionIndexes.Pop();
// else _selectionIndexes.Push(selection);
// }
// SelectionStart = selection;
// }
// }
// return base.OnPointerMove(context, args);
//}
//public override bool OnPointerLeave(IGuiContext context, PointerEventArgs args)
//{
// _startSelectionBox = false;
// return base.OnPointerLeave(context, args);
//}
//public override bool OnPointerUp(IGuiContext context, PointerEventArgs args)
//{
// _startSelectionBox = false;
// return base.OnPointerUp(context, args);
//}
private int FindNearestGlyphIndex(IGuiContext context, Point position)
{
var font = Font ?? context.DefaultFont;
var textInfo = GetTextInfo(context, Text, ContentRectangle, HorizontalTextAlignment, VerticalTextAlignment);
var i = 0;
foreach (var glyph in font.GetGlyphs(textInfo.Text, textInfo.Position))
{
var fontRegionWidth = glyph.Character?.TextureRegion?.Width ?? 0;
var glyphMiddle = (int) (glyph.Position.X + fontRegionWidth * 0.5f);
if (position.X >= glyphMiddle)
{
i++;
continue;
}
return i;
}
return i;
}
public override bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args)
{
switch (args.Key)
{
case Keys.Tab:
case Keys.Enter:
return true;
case Keys.Back:
if (Text.Length > 0)
{
if (SelectionStart > 0) // && _selectionIndexes.Count <= 1)
{
SelectionStart--;
Text = Text.Remove(SelectionStart, 1);
}
//else
//{
// var start = MathHelper.Min(_selectionIndexes.Last(), _selectionIndexes.Peek());
// var end = MathHelper.Max(_selectionIndexes.Last(), _selectionIndexes.Peek());
// Text = Text.Remove(start, end - start);
// _selectionIndexes.Clear();
//}
}
break;
case Keys.Delete:
if (SelectionStart < Text.Length) // && _selectionIndexes.Count <= 1)
{
Text = Text.Remove(SelectionStart, 1);
}
//else if (_selectionIndexes.Count > 1)
//{
// var start = MathHelper.Min(_selectionIndexes.Last(), _selectionIndexes.Peek());
// var end = MathHelper.Max(_selectionIndexes.Last(), _selectionIndexes.Peek());
// Text = Text.Remove(start, end - start);
// SelectionStart = 0; // yeah, nah.
// _selectionIndexes.Clear();
//}
break;
case Keys.Left:
if (SelectionStart > 0)
{
//if (_selectionIndexes.Count > 1)
//{
// if (_selectionIndexes.Last() < SelectionStart) SelectionStart = _selectionIndexes.Last();
// _selectionIndexes.Clear();
//}
//else
{
SelectionStart--;
}
}
break;
case Keys.Right:
if (SelectionStart < Text.Length)
{
//if (_selectionIndexes.Count > 1)
//{
// if (_selectionIndexes.Last() > SelectionStart) SelectionStart = _selectionIndexes.Last();
// _selectionIndexes.Clear();
//}
//else
{
SelectionStart++;
}
}
break;
case Keys.Home:
SelectionStart = 0;
//_selectionIndexes.Clear();
break;
case Keys.End:
SelectionStart = Text.Length;
//_selectionIndexes.Clear();
break;
default:
if (args.Character != null)
{
//if (_selectionIndexes.Count > 1)
//{
// var start = MathHelper.Min(_selectionIndexes.Last(), _selectionIndexes.Peek());
// var end = MathHelper.Max(_selectionIndexes.Last(), _selectionIndexes.Peek());
// Text = Text.Remove(start, end - start);
// _selectionIndexes.Clear();
//}
Text = Text.Insert(SelectionStart, args.Character.ToString());
SelectionStart++;
}
break;
}
_isCaretVisible = true;
return base.OnKeyPressed(context, args);
}
private const float _caretBlinkRate = 0.53f;
private float _nextCaretBlink = _caretBlinkRate;
private bool _isCaretVisible = true;
//private bool _startSelectionBox = false;
//private Stack<int> _selectionIndexes = new Stack<int>();
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
var text = PasswordCharacter.HasValue ? new string(PasswordCharacter.Value, Text.Length) : Text;
var textInfo = GetTextInfo(context, text, ContentRectangle, HorizontalTextAlignment, VerticalTextAlignment);
if (!string.IsNullOrWhiteSpace(textInfo.Text))
renderer.DrawText(textInfo.Font, textInfo.Text, textInfo.Position + TextOffset, textInfo.Color,
textInfo.ClippingRectangle);
if (IsFocused)
{
var caretRectangle = GetCaretRectangle(textInfo, SelectionStart);
if (_isCaretVisible)
renderer.DrawRectangle(caretRectangle, TextColor);
_nextCaretBlink -= deltaSeconds;
if (_nextCaretBlink <= 0)
{
_isCaretVisible = !_isCaretVisible;
_nextCaretBlink = _caretBlinkRate;
}
//if (_selectionIndexes.Count > 1)
//{
// var start = 0;
// var end = 0;
// var point = Vector2.Zero;
// if (_selectionIndexes.Last() > _selectionIndexes.Peek())
// {
// start = _selectionIndexes.Peek();
// end = _selectionIndexes.Last();
// point = caretRectangle.Position;
// }
// else
// {
// start = _selectionIndexes.Last();
// end = _selectionIndexes.Peek();
// point = GetCaretRectangle(textInfo, start).Position;
// }
// var selectionRectangle = textInfo.Font.GetStringRectangle(textInfo.Text.Substring(start, end - start), point);
// renderer.FillRectangle((Rectangle)selectionRectangle, Color.Black * 0.25f);
//}
}
}
//protected override string CreateBoxText(string text, BitmapFont font, float width)
//{
// return text;
//}
private Rectangle GetCaretRectangle(TextInfo textInfo, int index)
{
var caretRectangle = textInfo.Font.GetStringRectangle(textInfo.Text.Substring(0, index), textInfo.Position);
// TODO: Finish the caret position stuff when it's outside the clipping rectangle
if (caretRectangle.Right > ClippingRectangle.Right)
textInfo.Position.X -= caretRectangle.Right - ClippingRectangle.Right;
caretRectangle.X = caretRectangle.Right < ClippingRectangle.Right
? caretRectangle.Right
: ClippingRectangle.Right;
caretRectangle.Width = 1;
if (caretRectangle.Left < ClippingRectangle.Left)
{
textInfo.Position.X += ClippingRectangle.Left - caretRectangle.Left;
caretRectangle.X = ClippingRectangle.Left;
}
return (Rectangle) caretRectangle;
}
}
}
@@ -1,328 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended.Input.InputListeners;
namespace MonoGame.Extended.Gui.Controls
{
public class TextBox2 : Control
{
public TextBox2()
: this(null)
{
}
public TextBox2(string text)
{
Text = text ?? string.Empty;
HorizontalTextAlignment = HorizontalAlignment.Left;
VerticalTextAlignment = VerticalAlignment.Top;
}
private const float _caretBlinkRate = 0.53f;
private float _nextCaretBlink = _caretBlinkRate;
private bool _isCaretVisible = true;
private readonly List<StringBuilder> _lines = new List<StringBuilder>();
public string Text
{
get => string.Concat(_lines.SelectMany(s => $"{s}\n"));
set
{
_lines.Clear();
var line = new StringBuilder();
for (var i = 0; i < value.Length; i++)
{
var c = value[i];
if (c == '\n')
{
_lines.Add(line);
line = new StringBuilder();
}
else if(c != '\r')
{
line.Append(c);
}
}
_lines.Add(line);
}
}
public int CaretIndex => ColumnIndex * LineIndex + ColumnIndex;
public int LineIndex { get; set; }
public int ColumnIndex { get; set; }
public int TabStops { get; set; } = 4;
public override IEnumerable<Control> Children => Enumerable.Empty<Control>();
public string GetLineText(int lineIndex) => _lines[lineIndex].ToString();
public int GetLineLength(int lineIndex) => _lines[lineIndex].Length;
public override Size GetContentSize(IGuiContext context)
{
var font = Font ?? context.DefaultFont;
var stringSize = (Size)font.MeasureString(Text ?? string.Empty);
return new Size(stringSize.Width, stringSize.Height < font.LineHeight ? font.LineHeight : stringSize.Height);
}
public override bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args)
{
switch (args.Key)
{
case Keys.Tab:
Tab();
break;
case Keys.Back:
Backspace();
break;
case Keys.Delete:
Delete();
break;
case Keys.Left:
Left();
break;
case Keys.Right:
Right();
break;
case Keys.Up:
Up();
break;
case Keys.Down:
Down();
break;
case Keys.Home:
Home();
break;
case Keys.End:
End();
break;
case Keys.Enter:
Type('\n');
return true;
default:
if (args.Character.HasValue)
Type(args.Character.Value);
break;
}
_isCaretVisible = true;
return base.OnKeyPressed(context, args);
}
public void Type(char c)
{
switch (c)
{
case '\n':
var lineText = GetLineText(LineIndex);
var left = lineText.Substring(0, ColumnIndex);
var right = lineText.Substring(ColumnIndex);
_lines.Insert(LineIndex + 1, new StringBuilder(right));
_lines[LineIndex] = new StringBuilder(left);
LineIndex++;
Home();
break;
case '\t':
Tab();
break;
default:
_lines[LineIndex].Insert(ColumnIndex, c);
ColumnIndex++;
break;
}
}
public void Backspace()
{
if (ColumnIndex == 0 && LineIndex > 0)
{
var topLineLength = GetLineLength(LineIndex - 1);
if (RemoveLineBreak(LineIndex - 1))
{
LineIndex--;
ColumnIndex = topLineLength;
}
}
else if (Left())
{
RemoveCharacter(LineIndex, ColumnIndex);
}
}
public void Delete()
{
var lineLength = GetLineLength(LineIndex);
if (ColumnIndex == lineLength)
RemoveLineBreak(LineIndex);
else
RemoveCharacter(LineIndex, ColumnIndex);
}
public void RemoveCharacter(int lineIndex, int columnIndex)
{
_lines[lineIndex].Remove(columnIndex, 1);
}
public bool RemoveLineBreak(int lineIndex)
{
if (lineIndex < _lines.Count - 1)
{
var topLine = _lines[lineIndex];
var bottomLine = _lines[lineIndex + 1];
_lines.RemoveAt(lineIndex + 1);
topLine.Append(bottomLine);
return true;
}
return false;
}
public bool Home()
{
ColumnIndex = 0;
return true;
}
public bool End()
{
ColumnIndex = GetLineLength(LineIndex);
return true;
}
public bool Up()
{
if (LineIndex > 0)
{
LineIndex--;
if (ColumnIndex > GetLineLength(LineIndex))
ColumnIndex = GetLineLength(LineIndex);
return true;
}
return false;
}
public bool Down()
{
if (LineIndex < _lines.Count - 1)
{
LineIndex++;
if (ColumnIndex > GetLineLength(LineIndex))
ColumnIndex = GetLineLength(LineIndex);
return true;
}
return false;
}
public bool Left()
{
if (ColumnIndex == 0)
{
if (LineIndex == 0)
return false;
LineIndex--;
ColumnIndex = GetLineLength(LineIndex);
}
else
{
ColumnIndex--;
}
return true;
}
public bool Right()
{
if (ColumnIndex == _lines[LineIndex].Length)
{
if (LineIndex == _lines.Count - 1)
return false;
LineIndex++;
ColumnIndex = 0;
}
else
{
ColumnIndex++;
}
return true;
}
public bool Tab()
{
var spaces = TabStops - ColumnIndex % TabStops;
for (var s = 0; s < spaces; s++)
Type(' ');
return spaces > 0;
}
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
{
base.Draw(context, renderer, deltaSeconds);
var text = Text;
var textInfo = GetTextInfo(context, text, ContentRectangle, HorizontalTextAlignment, VerticalTextAlignment);
if (!string.IsNullOrWhiteSpace(textInfo.Text))
renderer.DrawText(textInfo.Font, textInfo.Text, textInfo.Position + TextOffset, textInfo.Color, textInfo.ClippingRectangle);
if (IsFocused)
{
var caretRectangle = GetCaretRectangle(textInfo);
if (_isCaretVisible)
renderer.DrawRectangle(caretRectangle, TextColor);
_nextCaretBlink -= deltaSeconds;
if (_nextCaretBlink <= 0)
{
_isCaretVisible = !_isCaretVisible;
_nextCaretBlink = _caretBlinkRate;
}
}
}
private Rectangle GetCaretRectangle(TextInfo textInfo)
{
var font = textInfo.Font;
var text = GetLineText(LineIndex);
var offset = new Vector2(0, font.LineHeight * LineIndex);
var caretRectangle = font.GetStringRectangle(text.Substring(0, ColumnIndex), textInfo.Position + offset);
// TODO: Finish the caret position stuff when it's outside the clipping rectangle
if (caretRectangle.Right > ClippingRectangle.Right)
textInfo.Position.X -= caretRectangle.Right - ClippingRectangle.Right;
caretRectangle.X = caretRectangle.Right < ClippingRectangle.Right ? caretRectangle.Right : ClippingRectangle.Right;
caretRectangle.Width = 1;
if (caretRectangle.Left < ClippingRectangle.Left)
{
textInfo.Position.X += ClippingRectangle.Left - caretRectangle.Left;
caretRectangle.X = ClippingRectangle.Left;
}
return (Rectangle)caretRectangle;
}
}
}
@@ -1,98 +0,0 @@
using System;
namespace MonoGame.Extended.Gui.Controls
{
public class ToggleButton : Button
{
public ToggleButton()
{
}
public event EventHandler CheckedStateChanged;
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
if (_isChecked != value)
{
_isChecked = value;
CheckedStyle?.ApplyIf(this, _isChecked);
CheckedStateChanged?.Invoke(this, EventArgs.Empty);
}
}
}
private ControlStyle _checkedStyle;
public ControlStyle CheckedStyle
{
get { return _checkedStyle; }
set
{
if (_checkedStyle != value)
{
_checkedStyle = value;
CheckedStyle?.ApplyIf(this, _isChecked);
}
}
}
private ControlStyle _checkedHoverStyle;
public ControlStyle CheckedHoverStyle
{
get { return _checkedHoverStyle; }
set
{
if (_checkedHoverStyle != value)
{
_checkedHoverStyle = value;
CheckedHoverStyle?.ApplyIf(this, _isChecked && IsHovered);
}
}
}
public override bool OnPointerUp(IGuiContext context, PointerEventArgs args)
{
base.OnPointerUp(context, args);
if (BoundingRectangle.Contains(args.Position))
{
HoverStyle?.Revert(this);
CheckedHoverStyle?.Revert(this);
IsChecked = !IsChecked;
if (IsChecked)
CheckedHoverStyle?.Apply(this);
else
HoverStyle?.Apply(this);
}
return true;
}
public override bool OnPointerEnter(IGuiContext context, PointerEventArgs args)
{
if (IsChecked)
{
CheckedHoverStyle?.Apply(this);
return true;
}
return base.OnPointerEnter(context, args);
}
public override bool OnPointerLeave(IGuiContext context, PointerEventArgs args)
{
if (IsChecked)
{
CheckedHoverStyle?.Revert(this);
return true;
}
return base.OnPointerLeave(context, args);
}
}
}
@@ -1,86 +0,0 @@
using System;
using System.Linq;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Gui.Controls
{
public class UniformGrid : LayoutControl
{
public UniformGrid()
{
}
public int Columns { get; set; }
public int Rows { get; set; }
public override Size GetContentSize(IGuiContext context)
{
var columns = Columns == 0 ? (int)Math.Ceiling(Math.Sqrt(Items.Count)) : Columns;
var rows = Rows == 0 ? (int)Math.Ceiling((float)Items.Count / columns) : Rows;
var sizes = Items
.Select(control => control.CalculateActualSize(context))
.ToArray();
var minCellWidth = sizes.Max(s => s.Width);
var minCellHeight = sizes.Max(s => s.Height);
return new Size(minCellWidth * columns, minCellHeight * rows);
}
protected override void Layout(IGuiContext context, Rectangle rectangle)
{
var gridInfo = CalculateGridInfo(context, new Point(rectangle.Width, rectangle.Height));
var columnIndex = 0;
var rowIndex = 0;
var cellWidth = HorizontalAlignment == HorizontalAlignment.Stretch ? gridInfo.MaxCellWidth : gridInfo.MinCellWidth;
var cellHeight = VerticalAlignment == VerticalAlignment.Stretch ? gridInfo.MaxCellHeight : gridInfo.MinCellHeight;
foreach (var control in Items)
{
var x = columnIndex * cellWidth + rectangle.X;
var y = rowIndex * cellHeight + rectangle.Y;
PlaceControl(context, control, x, y, cellWidth, cellHeight);
columnIndex++;
if (columnIndex > gridInfo.Columns - 1)
{
columnIndex = 0;
rowIndex++;
}
}
}
private struct GridInfo
{
public float MinCellWidth;
public float MinCellHeight;
public float MaxCellWidth;
public float MaxCellHeight;
public float Columns;
public float Rows;
public SizeF MinCellSize => new SizeF(MinCellWidth * Columns, MinCellHeight * Rows);
}
private GridInfo CalculateGridInfo(IGuiContext context, SizeF availableSize)
{
var columns = Columns == 0 ? (int)Math.Ceiling(Math.Sqrt(Items.Count)) : Columns;
var rows = Rows == 0 ? (int)Math.Ceiling((float)Items.Count / columns) : Rows;
var maxCellWidth = availableSize.Width / columns;
var maxCellHeight = availableSize.Height / rows;
var sizes = Items
.Select(control => control.CalculateActualSize(context)) // LayoutHelper.GetSizeWithMargins(control, context, new Size2(maxCellWidth, maxCellHeight)))
.ToArray();
var maxControlWidth = sizes.Length == 0 ? 0 : sizes.Max(s => s.Width);
var maxControlHeight = sizes.Length == 0 ? 0 : sizes.Max(s => s.Height);
return new GridInfo
{
Columns = columns,
Rows = rows,
MinCellWidth = Math.Min(maxControlWidth, maxCellWidth),
MinCellHeight = Math.Min(maxControlHeight, maxCellHeight),
MaxCellWidth = maxCellWidth,
MaxCellHeight = maxCellHeight
};
}
}
}
-11
View File
@@ -1,11 +0,0 @@
using Microsoft.Xna.Framework;
using MonoGame.Extended.Graphics;
namespace MonoGame.Extended.Gui
{
public class Cursor
{
public Texture2DRegion TextureRegion { get; set; }
public Color Color { get; set; } = Color.White;
}
}
-126
View File
@@ -1,126 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text.Json.Serialization;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Graphics;
namespace MonoGame.Extended.Gui
{
public class Binding
{
public Binding(object viewModel, string viewModelProperty, string viewProperty)
{
ViewModel = viewModel;
ViewModelProperty = viewModelProperty;
ViewProperty = viewProperty;
}
public object ViewModel { get; }
public string ViewModelProperty { get; }
public string ViewProperty { get; }
}
public abstract class Element
{
public string Name { get; set; }
public Point Position { get; set; }
public Point Origin { get; set; }
public Color BackgroundColor { get; set; }
public Color BorderColor { get; set; } = Color.White;
public int BorderThickness { get; set; } = 0;
private Texture2DRegion _backgroundRegion;
public Texture2DRegion BackgroundRegion
{
get => _backgroundRegion;
set
{
_backgroundRegion = value;
if (_backgroundRegion != null && BackgroundColor == Color.Transparent)
BackgroundColor = Color.White;
}
}
public List<Binding> Bindings { get; } = new List<Binding>();
protected void OnPropertyChanged(string propertyName)
{
foreach (var binding in Bindings)
{
if (binding.ViewProperty == propertyName)
{
var value = GetType()
.GetTypeInfo()
.GetDeclaredProperty(binding.ViewProperty)
.GetValue(this);
binding.ViewModel
.GetType()
.GetTypeInfo()
.GetDeclaredProperty(binding.ViewModelProperty)
.SetValue(binding.ViewModel, value);
}
}
}
private Size _size;
public Size Size
{
get => _size;
set
{
_size = value;
OnSizeChanged();
}
}
protected virtual void OnSizeChanged() { }
public int MinWidth { get; set; }
public int MinHeight { get; set; }
public int MaxWidth { get; set; } = int.MaxValue;
public int MaxHeight { get; set; } = int.MaxValue;
public int Width
{
get => Size.Width;
set => Size = new Size(value, Size.Height);
}
public int Height
{
get => Size.Height;
set => Size = new Size(Size.Width, value);
}
public Size ActualSize { get; internal set; }
public abstract void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds);
}
public abstract class Element<TParent> : Element, IRectangular
where TParent : IRectangular
{
[EditorBrowsable(EditorBrowsableState.Never)]
[JsonIgnore]
public TParent Parent { get; internal set; }
[EditorBrowsable(EditorBrowsableState.Never)]
[JsonIgnore]
public Rectangle BoundingRectangle
{
get
{
var offset = Point.Zero;
if (Parent != null)
offset = Parent.BoundingRectangle.Location;
var position = offset + Position - ActualSize * Origin;
return new Rectangle(position.X, position.Y, ActualSize.Width, ActualSize.Height);
}
}
}
}
@@ -1,98 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using MonoGame.Extended.Gui.Controls;
namespace MonoGame.Extended.Gui
{
public abstract class ElementCollection<TChild, TParent> : IList<TChild>
where TParent : class, IRectangular
where TChild : Element<TParent>
{
private readonly TParent _parent;
private readonly List<TChild> _list = new List<TChild>();
public Action<TChild> ItemAdded { get; set; }
public Action<TChild> ItemRemoved { get; set; }
protected ElementCollection(TParent parent)
{
_parent = parent;
}
public IEnumerator<TChild> GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_list).GetEnumerator();
}
public void Add(TChild item)
{
item.Parent = _parent;
_list.Add(item);
ItemAdded?.Invoke(item);
}
public void Clear()
{
foreach (var child in _list)
{
child.Parent = null;
ItemRemoved?.Invoke(child);
}
_list.Clear();
}
public bool Contains(TChild item)
{
return _list.Contains(item);
}
public void CopyTo(TChild[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
public bool Remove(TChild item)
{
item.Parent = null;
ItemRemoved?.Invoke(item);
return _list.Remove(item);
}
public int Count => _list.Count;
public bool IsReadOnly => ((ICollection<Control>)_list).IsReadOnly;
public int IndexOf(TChild item)
{
return _list.IndexOf(item);
}
public void Insert(int index, TChild item)
{
item.Parent = _parent;
_list.Insert(index, item);
ItemAdded?.Invoke(item);
}
public void RemoveAt(int index)
{
var child = _list[index];
child.Parent = null;
_list.RemoveAt(index);
ItemRemoved?.Invoke(child);
}
public TChild this[int index]
{
get { return _list[index]; }
set { _list[index] = value; }
}
}
}
@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
<Description>A GUI system for FNA written from the ground up to make FNA more awesome.</Description>
<PackageTags>fna gui</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MonoGame.Extended.Input\FNA.Extended.Input.csproj" />
<ProjectReference Include="..\MonoGame.Extended\FNA.Extended.csproj" />
</ItemGroup>
</Project>
@@ -1,82 +0,0 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Graphics;
using MonoGame.Extended.TextureAtlases;
namespace MonoGame.Extended.Gui
{
public interface IGuiRenderer
{
void Begin();
void DrawRegion(Texture2DRegion textureRegion, Rectangle rectangle, Color color, Rectangle? clippingRectangle = null);
void DrawRegion(Texture2DRegion textureRegion, Vector2 position, Color color, Rectangle? clippingRectangle = null);
void DrawText(BitmapFont font, string text, Vector2 position, Color color, Rectangle? clippingRectangle = null);
void DrawRectangle(Rectangle rectangle, Color color, float thickness = 1f, Rectangle? clippingRectangle = null);
void FillRectangle(Rectangle rectangle, Color color, Rectangle? clippingRectangle = null);
void End();
}
public class GuiSpriteBatchRenderer : IGuiRenderer
{
private readonly Func<Matrix> _getTransformMatrix;
private readonly SpriteBatch _spriteBatch;
public GuiSpriteBatchRenderer(GraphicsDevice graphicsDevice, Func<Matrix> getTransformMatrix)
{
_getTransformMatrix = getTransformMatrix;
_spriteBatch = new SpriteBatch(graphicsDevice);
}
public SpriteSortMode SortMode { get; set; }
public BlendState BlendState { get; set; } = BlendState.AlphaBlend;
public SamplerState SamplerState { get; set; } = SamplerState.PointClamp;
public DepthStencilState DepthStencilState { get; set; } = DepthStencilState.Default;
public RasterizerState RasterizerState { get; set; } = RasterizerState.CullNone;
public Effect Effect { get; set; }
public void Begin()
{
_spriteBatch.Begin(SortMode, BlendState, SamplerState, DepthStencilState, RasterizerState, Effect, _getTransformMatrix());
}
public void End()
{
_spriteBatch.End();
}
public void DrawRegion(Texture2DRegion textureRegion, Rectangle rectangle, Color color, Rectangle? clippingRectangle = null)
{
if (textureRegion != null)
_spriteBatch.Draw(textureRegion, rectangle, color, clippingRectangle);
}
public void DrawRegion(Texture2DRegion textureRegion, Vector2 position, Color color, Rectangle? clippingRectangle = null)
{
if (textureRegion != null)
_spriteBatch.Draw(textureRegion, position, color, clippingRectangle);
}
public void DrawText(BitmapFont font, string text, Vector2 position, Color color, Rectangle? clippingRectangle = null)
{
_spriteBatch.DrawString(font, text, position, color, clippingRectangle);
}
public void DrawRectangle(Rectangle rectangle, Color color, float thickness = 1f, Rectangle? clippingRectangle = null)
{
if (clippingRectangle.HasValue)
rectangle = rectangle.Clip(clippingRectangle.Value);
_spriteBatch.DrawRectangle(rectangle, color, thickness);
}
public void FillRectangle(Rectangle rectangle, Color color, Rectangle? clippingRectangle = null)
{
if (clippingRectangle.HasValue)
rectangle = rectangle.Clip(clippingRectangle.Value);
_spriteBatch.FillRectangle(rectangle, color);
}
}
}
-265
View File
@@ -1,265 +0,0 @@
using Microsoft.Xna.Framework;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Gui.Controls;
using MonoGame.Extended.Input.InputListeners;
using MonoGame.Extended.ViewportAdapters;
using System;
using System.Linq;
namespace MonoGame.Extended.Gui
{
public interface IGuiContext
{
BitmapFont DefaultFont { get; }
Vector2 CursorPosition { get; }
Control FocusedControl { get; }
void SetFocus(Control focusedControl);
}
public class GuiSystem : IGuiContext, IRectangular
{
private readonly ViewportAdapter _viewportAdapter;
private readonly IGuiRenderer _renderer;
private readonly MouseListener _mouseListener;
private readonly TouchListener _touchListener;
private readonly KeyboardListener _keyboardListener;
private Control _preFocusedControl;
public GuiSystem(ViewportAdapter viewportAdapter, IGuiRenderer renderer)
{
_viewportAdapter = viewportAdapter;
_renderer = renderer;
_mouseListener = new MouseListener(viewportAdapter);
_mouseListener.MouseDown += (s, e) => OnPointerDown(PointerEventArgs.FromMouseArgs(e));
_mouseListener.MouseMoved += (s, e) => OnPointerMoved(PointerEventArgs.FromMouseArgs(e));
_mouseListener.MouseUp += (s, e) => OnPointerUp(PointerEventArgs.FromMouseArgs(e));
_mouseListener.MouseWheelMoved += (s, e) => FocusedControl?.OnScrolled(e.ScrollWheelDelta);
_touchListener = new TouchListener(viewportAdapter);
_touchListener.TouchStarted += (s, e) => OnPointerDown(PointerEventArgs.FromTouchArgs(e));
_touchListener.TouchMoved += (s, e) => OnPointerMoved(PointerEventArgs.FromTouchArgs(e));
_touchListener.TouchEnded += (s, e) => OnPointerUp(PointerEventArgs.FromTouchArgs(e));
_keyboardListener = new KeyboardListener();
_keyboardListener.KeyTyped += (sender, args) => PropagateDown(FocusedControl, x => x.OnKeyTyped(this, args));
_keyboardListener.KeyPressed += (sender, args) => PropagateDown(FocusedControl, x => x.OnKeyPressed(this, args));
}
public Control FocusedControl { get; private set; }
public Control HoveredControl { get; private set; }
private Screen _activeScreen;
public Screen ActiveScreen
{
get => _activeScreen;
set
{
if (_activeScreen != value)
{
_activeScreen = value;
if(_activeScreen != null)
InitializeScreen(_activeScreen);
}
}
}
public Rectangle BoundingRectangle => _viewportAdapter.BoundingRectangle;
public Vector2 CursorPosition { get; set; }
public BitmapFont DefaultFont => Skin.Default?.DefaultFont;
private void InitializeScreen(Screen screen)
{
screen.Layout(this, BoundingRectangle);
}
public void ClientSizeChanged()
{
//ActiveScreen?.Content?.InvalidateMeasure();
ActiveScreen?.Layout(this, BoundingRectangle);
}
public void Update(GameTime gameTime)
{
if(ActiveScreen == null)
return;
_touchListener.Update(gameTime);
_mouseListener.Update(gameTime);
_keyboardListener.Update(gameTime);
var deltaSeconds = gameTime.GetElapsedSeconds();
if (ActiveScreen != null && ActiveScreen.IsVisible)
UpdateControl(ActiveScreen.Content, deltaSeconds);
//if (ActiveScreen.IsLayoutRequired)
// ActiveScreen.Layout(this, BoundingRectangle);
ActiveScreen.Update(gameTime);
}
public void Draw(GameTime gameTime)
{
var deltaSeconds = gameTime.GetElapsedSeconds();
_renderer.Begin();
if (ActiveScreen != null && ActiveScreen.IsVisible)
{
DrawControl(ActiveScreen.Content, deltaSeconds);
//DrawWindows(ActiveScreen.Windows, deltaSeconds);
}
var cursor = Skin.Default?.Cursor;
if (cursor != null)
_renderer.DrawRegion(cursor.TextureRegion, CursorPosition, cursor.Color);
_renderer.End();
}
//private void DrawWindows(WindowCollection windows, float deltaSeconds)
//{
// foreach (var window in windows)
// {
// window.Draw(this, _renderer, deltaSeconds);
// DrawChildren(window.Controls, deltaSeconds);
// }
//}
public void UpdateControl(Control control, float deltaSeconds)
{
if (control.IsVisible)
{
control.Update(this, deltaSeconds);
foreach (var childControl in control.Children)
UpdateControl(childControl, deltaSeconds);
}
}
private void DrawControl(Control control, float deltaSeconds)
{
if (control.IsVisible)
{
control.Draw(this, _renderer, deltaSeconds);
foreach (var childControl in control.Children)
DrawControl(childControl, deltaSeconds);
}
}
private void OnPointerDown(PointerEventArgs args)
{
if (ActiveScreen == null || !ActiveScreen.IsVisible)
return;
_preFocusedControl = FindControlAtPoint(args.Position);
PropagateDown(HoveredControl, x => x.OnPointerDown(this, args));
}
private void OnPointerUp(PointerEventArgs args)
{
if (ActiveScreen == null || !ActiveScreen.IsVisible)
return;
var postFocusedControl = FindControlAtPoint(args.Position);
if (_preFocusedControl == postFocusedControl)
{
SetFocus(postFocusedControl);
}
_preFocusedControl = null;
PropagateDown(HoveredControl, x => x.OnPointerUp(this, args));
}
private void OnPointerMoved(PointerEventArgs args)
{
CursorPosition = args.Position.ToVector2();
if (ActiveScreen == null || !ActiveScreen.IsVisible)
return;
var hoveredControl = FindControlAtPoint(args.Position);
if (HoveredControl != hoveredControl)
{
if (HoveredControl != null && (hoveredControl == null || !hoveredControl.HasParent(HoveredControl)))
PropagateDown(HoveredControl, x => x.OnPointerLeave(this, args));
HoveredControl = hoveredControl;
PropagateDown(HoveredControl, x => x.OnPointerEnter(this, args));
}
else
{
PropagateDown(HoveredControl, x => x.OnPointerMove(this, args));
}
}
public void SetFocus(Control focusedControl)
{
if (FocusedControl != focusedControl)
{
if (FocusedControl != null)
{
FocusedControl.IsFocused = false;
PropagateDown(FocusedControl, x => x.OnUnfocus(this));
}
FocusedControl = focusedControl;
if (FocusedControl != null)
{
FocusedControl.IsFocused = true;
PropagateDown(FocusedControl, x => x.OnFocus(this));
}
}
}
/// <summary>
/// Method is meant to loop down the parents control to find a suitable event control. If the predicate returns false
/// it will continue down the control tree.
/// </summary>
/// <param name="control">The control we want to check against</param>
/// <param name="predicate">A function to check if the propagation should resume, if returns false it will continue down the tree.</param>
private static void PropagateDown(Control control, Func<Control, bool> predicate)
{
while(control != null && predicate(control))
{
control = control.Parent;
}
}
private Control FindControlAtPoint(Point point)
{
if (ActiveScreen == null || !ActiveScreen.IsVisible)
return null;
return FindControlAtPoint(ActiveScreen.Content, point);
}
private Control FindControlAtPoint(Control control, Point point)
{
foreach (var controlChild in control.Children.Reverse())
{
var c = FindControlAtPoint(controlChild, point);
if (c != null)
return c;
}
if (control.IsVisible && control.Contains(this, point))
return control;
return null;
}
}
}
@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>$(DefineConstants);KNI</DefineConstants>
<Description>A GUI system for KNI written from the ground up to make KNI more awesome.</Description>
<PackageTags>kni gui</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MonoGame.Extended.Input\KNI.Extended.Input.csproj" />
<ProjectReference Include="..\MonoGame.Extended\KNI.Extended.csproj" />
</ItemGroup>
</Project>
@@ -1,65 +0,0 @@
using System;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Gui.Controls;
namespace MonoGame.Extended.Gui
{
public enum HorizontalAlignment { Left, Right, Centre, Stretch }
public enum VerticalAlignment { Top, Bottom, Centre, Stretch }
public static class LayoutHelper
{
public static void PlaceControl(IGuiContext context, Control control, float x, float y, float width, float height)
{
var rectangle = new Rectangle((int)x, (int)y, (int)width, (int)height);
var desiredSize = control.CalculateActualSize(context);
var alignedRectangle = AlignRectangle(control.HorizontalAlignment, control.VerticalAlignment, desiredSize, rectangle);
control.Position = new Point(control.Margin.Left + alignedRectangle.X, control.Margin.Top + alignedRectangle.Y);
control.ActualSize = new Size(alignedRectangle.Width, alignedRectangle.Height) - control.Margin.Size;
control.InvalidateMeasure();
}
public static Rectangle AlignRectangle(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, Size size, Rectangle targetRectangle)
{
var x = GetHorizontalPosition(horizontalAlignment, size, targetRectangle);
var y = GetVerticalPosition(verticalAlignment, size, targetRectangle);
var width = horizontalAlignment == HorizontalAlignment.Stretch ? targetRectangle.Width : size.Width;
var height = verticalAlignment == VerticalAlignment.Stretch ? targetRectangle.Height : size.Height;
return new Rectangle(x, y, width, height);
}
public static int GetHorizontalPosition(HorizontalAlignment horizontalAlignment, Size size, Rectangle targetRectangle)
{
switch (horizontalAlignment)
{
case HorizontalAlignment.Stretch:
case HorizontalAlignment.Left:
return targetRectangle.X;
case HorizontalAlignment.Right:
return targetRectangle.Right - size.Width;
case HorizontalAlignment.Centre:
return targetRectangle.X + targetRectangle.Width / 2 - size.Width / 2;
default:
throw new ArgumentOutOfRangeException(nameof(horizontalAlignment), horizontalAlignment, $"{horizontalAlignment} is not supported");
}
}
public static int GetVerticalPosition(VerticalAlignment verticalAlignment, Size size, Rectangle targetRectangle)
{
switch (verticalAlignment)
{
case VerticalAlignment.Stretch:
case VerticalAlignment.Top:
return targetRectangle.Y;
case VerticalAlignment.Bottom:
return targetRectangle.Bottom - size.Height;
case VerticalAlignment.Centre:
return targetRectangle.Y + targetRectangle.Height / 2 - size.Height / 2;
default:
throw new ArgumentOutOfRangeException(nameof(verticalAlignment), verticalAlignment, $"{verticalAlignment} is not supported");
}
}
}
}
@@ -1,147 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Gui.Controls;
namespace MonoGame.Extended.Gui.Markup
{
public class MarkupParser
{
public MarkupParser()
{
}
private static readonly Dictionary<string, Type> _controlTypes =
typeof(Control).Assembly
.ExportedTypes
.Where(t => t.IsSubclassOf(typeof(Control)))
.ToDictionary(t => t.Name, StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<Type, Func<string, object>> _converters =
new Dictionary<Type, Func<string, object>>
{
{typeof(object), s => s},
{typeof(string), s => s},
{typeof(bool), s => bool.Parse(s)},
{typeof(int), s => int.Parse(s)},
{typeof(Color), s => s.StartsWith("#") ? ColorHelper.FromHex(s) : ColorHelper.FromName(s)}
};
private static object ConvertValue(Type propertyType, string input, object dataContext)
{
var value = ParseBinding(input, dataContext);
if (_converters.TryGetValue(propertyType, out var converter))
return converter(value); //property.SetValue(control, converter(value));
if (propertyType.IsEnum)
return
Enum.Parse(propertyType, value,
true); // property.SetValue(control, Enum.Parse(propertyType, value, true));
throw new InvalidOperationException($"Converter not found for {propertyType}");
}
private static object ParseChildNode(XmlNode node, Control parent, object dataContext)
{
if (node is XmlText)
return node.InnerText.Trim();
if (_controlTypes.TryGetValue(node.Name, out var type))
{
var typeInfo = type.GetTypeInfo();
var control = (Control) Activator.CreateInstance(type);
// ReSharper disable once AssignNullToNotNullAttribute
foreach (var attribute in node.Attributes.Cast<XmlAttribute>())
{
var property = typeInfo.GetProperty(attribute.Name);
if (property != null)
{
var value = ConvertValue(property.PropertyType, attribute.Value, dataContext);
property.SetValue(control, value);
}
else
{
var parts = attribute.Name.Split('.');
var parentType = parts[0];
var propertyName = parts[1];
var propertyType = parent.GetAttachedPropertyType(propertyName);
var propertyValue = ConvertValue(propertyType, attribute.Value, dataContext);
if (!string.Equals(parent.GetType().Name, parentType, StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException(
$"Attached properties are only supported on the immediate parent type {parentType}");
control.SetAttachedProperty(propertyName, propertyValue);
}
}
if (node.HasChildNodes)
{
switch (control)
{
case ContentControl contentControl:
if (node.ChildNodes.Count > 1)
throw new InvalidOperationException("A content control can only have one child");
contentControl.Content = ParseChildNode(node.ChildNodes[0], control, dataContext);
break;
case LayoutControl layoutControl:
foreach (var childControl in ParseChildNodes(node.ChildNodes, control, dataContext))
layoutControl.Items.Add(childControl as Control);
break;
}
}
return control;
}
throw new InvalidOperationException($"Unknown control type {node.Name}");
}
private static string ParseBinding(string expression, object dataContext)
{
if (dataContext != null && expression.StartsWith("{{") && expression.EndsWith("}}"))
{
var binding = expression.Substring(2, expression.Length - 4);
var bindingValue = dataContext
.GetType()
.GetProperty(binding)
?.GetValue(dataContext);
return $"{bindingValue}";
}
return expression;
}
private static IEnumerable<object> ParseChildNodes(XmlNodeList nodes, Control parent, object dataContext)
{
foreach (var node in nodes.Cast<XmlNode>())
{
if (node.Name == "xml")
{
// TODO: Validate header
}
else
{
yield return ParseChildNode(node, parent, dataContext);
}
}
}
public Control Parse(string filePath, object dataContext)
{
var d = new XmlDocument();
d.Load(filePath);
return ParseChildNodes(d.ChildNodes, null, dataContext)
.LastOrDefault() as Control;
}
}
}
@@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>A GUI system for MonoGame written from the ground up to make MonoGame more awesome.</Description>
<PackageTags>monogame gui</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MonoGame.Extended.Input\MonoGame.Extended.Input.csproj" />
<ProjectReference Include="..\MonoGame.Extended\MonoGame.Extended.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +0,0 @@
namespace MonoGame.Extended.Gui
{
public enum Orientation { Horizontal, Vertical }
}
@@ -1,42 +0,0 @@
using System;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Input;
using MonoGame.Extended.Input.InputListeners;
namespace MonoGame.Extended.Gui
{
public class PointerEventArgs : EventArgs
{
private PointerEventArgs()
{
}
public Point Position { get; private set; }
public MouseButton Button { get; private set; }
public int ScrollWheelDelta { get; private set; }
public int ScrollWheelValue { get; private set; }
public TimeSpan Time { get; private set; }
public static PointerEventArgs FromMouseArgs(MouseEventArgs args)
{
return new PointerEventArgs
{
Position = args.Position,
Button = args.Button,
ScrollWheelDelta = args.ScrollWheelDelta,
ScrollWheelValue = args.ScrollWheelValue,
Time = args.Time
};
}
public static PointerEventArgs FromTouchArgs(TouchEventArgs args)
{
return new PointerEventArgs
{
Position = args.Position,
Button = MouseButton.Left,
Time = args.Time
};
}
}
}
-140
View File
@@ -1,140 +0,0 @@
using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using MonoGame.Extended.Gui.Controls;
using MonoGame.Extended.Gui.Serialization;
namespace MonoGame.Extended.Gui
{
public class Screen //: Element<GuiSystem>, IDisposable
{
public Screen()
{
//Windows = new WindowCollection(this) { ItemAdded = w => _isLayoutRequired = true };
}
public virtual void Dispose()
{
}
private Control _content;
[JsonPropertyOrder(1)]
public Control Content
{
get { return _content; }
set
{
if (_content != value)
{
_content = value;
_isLayoutRequired = true;
}
}
}
//[JsonIgnore]
//public WindowCollection Windows { get; }
public float Width { get; private set; }
public float Height { get; private set; }
public SizeF Size => new SizeF(Width, Height);
public bool IsVisible { get; set; } = true;
private bool _isLayoutRequired;
[JsonIgnore]
public bool IsLayoutRequired => _isLayoutRequired || Content.IsLayoutRequired;
public virtual void Update(GameTime gameTime)
{
}
public void Show()
{
IsVisible = true;
}
public void Hide()
{
IsVisible = false;
}
public T FindControl<T>(string name)
where T : Control
{
return FindControl<T>(Content, name);
}
private static T FindControl<T>(Control rootControl, string name)
where T : Control
{
if (rootControl.Name == name)
return rootControl as T;
foreach (var childControl in rootControl.Children)
{
var control = FindControl<T>(childControl, name);
if (control != null)
return control;
}
return null;
}
public void Layout(IGuiContext context, Rectangle rectangle)
{
Width = rectangle.Width;
Height = rectangle.Height;
LayoutHelper.PlaceControl(context, Content, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
//foreach (var window in Windows)
// LayoutHelper.PlaceWindow(context, window, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
_isLayoutRequired = false;
Content.IsLayoutRequired = false;
}
//public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
//{
// renderer.DrawRectangle(BoundingRectangle, Color.Green);
//}
public static Screen FromStream(ContentManager contentManager, Stream stream, params Type[] customControlTypes)
{
return FromStream<Screen>(contentManager, stream, customControlTypes);
}
public static TScreen FromStream<TScreen>(ContentManager contentManager, Stream stream, params Type[] customControlTypes)
where TScreen : Screen
{
var skinService = new SkinService();
var options = GuiJsonSerializerOptionsProvider.GetOptions(contentManager, customControlTypes);
options.Converters.Add(new SkinJsonConverter(contentManager, skinService, customControlTypes));
options.Converters.Add(new ControlJsonConverter(skinService, customControlTypes));
return JsonSerializer.Deserialize<TScreen>(stream, options);
}
public static Screen FromFile(ContentManager contentManager, string path, params Type[] customControlTypes)
{
using (var stream = TitleContainer.OpenStream(path))
{
return FromStream<Screen>(contentManager, stream, customControlTypes);
}
}
public static TScreen FromFile<TScreen>(ContentManager contentManager, string path, params Type[] customControlTypes)
where TScreen : Screen
{
using (var stream = TitleContainer.OpenStream(path))
{
return FromStream<TScreen>(contentManager, stream, customControlTypes);
}
}
}
}
@@ -1,10 +0,0 @@
namespace MonoGame.Extended.Gui
{
//public class ScreenCollection : ElementCollection<Screen, GuiSystem>
//{
// public ScreenCollection(GuiSystem parent)
// : base(parent)
// {
// }
//}
}
@@ -1,67 +0,0 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using MonoGame.Extended.Gui.Controls;
namespace MonoGame.Extended.Gui.Serialization
{
public class ControlJsonConverter : JsonConverter<Control>
{
private readonly IGuiSkinService _guiSkinService;
private readonly ControlStyleJsonConverter _styleConverter;
private const string _styleProperty = "Style";
public ControlJsonConverter(IGuiSkinService guiSkinService, params Type[] customControlTypes)
{
_guiSkinService = guiSkinService;
_styleConverter = new ControlStyleJsonConverter(customControlTypes);
}
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Control);
/// <inheritdoc />
public override Control Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var style = _styleConverter.Read(ref reader, typeToConvert, options);
var template = GetControlTemplate(style);
var skin = _guiSkinService.Skin;
var control = skin.Create(style.TargetType, template);
var itemsControl = control as ItemsControl;
if (itemsControl != null)
{
object childControls;
if (style.TryGetValue(nameof(ItemsControl.Items), out childControls))
{
var controlCollection = childControls as ControlCollection;
if (controlCollection != null)
{
foreach (var child in controlCollection)
itemsControl.Items.Add(child);
}
}
}
style.Apply(control);
return control;
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, Control value, JsonSerializerOptions options) { }
private static string GetControlTemplate(ControlStyle style)
{
object template;
if (style.TryGetValue(_styleProperty, out template))
return template as string;
return null;
}
}
}
@@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using MonoGame.Extended.Collections;
using MonoGame.Extended.Gui.Controls;
namespace MonoGame.Extended.Gui.Serialization
{
public class ControlStyleJsonConverter : JsonConverter<ControlStyle>
{
private readonly Dictionary<string, Type> _controlTypes;
private const string _typeProperty = "Type";
private const string _nameProperty = "Name";
public ControlStyleJsonConverter(params Type[] customControlTypes)
{
_controlTypes = typeof(Control)
.GetTypeInfo()
.Assembly
.ExportedTypes
.Concat(customControlTypes)
.Where(t => t.GetTypeInfo().IsSubclassOf(typeof(Control)))
.ToDictionary(t => t.Name);
}
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(ControlStyle);
/// <inheritdoc />
public override ControlStyle Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options);
var name = dictionary.GetValueOrDefault(_nameProperty) as string;
var typeName = dictionary.GetValueOrDefault(_typeProperty) as string;
if (!_controlTypes.TryGetValue(typeName, out Type controlType))
throw new FormatException("invalid control type: " + typeName);
var targetType = typeName != null ? controlType : typeof(Control);
var properties = targetType
.GetRuntimeProperties()
.ToDictionary(p => p.Name);
var style = new ControlStyle(name, targetType);
foreach (var keyValuePair in dictionary.Where(i => i.Key != _typeProperty))
{
var propertyName = keyValuePair.Key;
var rawValue = keyValuePair.Value;
PropertyInfo propertyInfo;
var value = properties.TryGetValue(propertyName, out propertyInfo)
? DeserializeValueAs(rawValue, propertyInfo.PropertyType)
: DeserializeValueAs(rawValue, typeof(object));
style.Add(propertyName, value);
}
return style;
}
private static object DeserializeValueAs(object value, Type type)
{
var json = JsonSerializer.Serialize(value, type);
return JsonSerializer.Deserialize(json, type);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, ControlStyle value, JsonSerializerOptions options)
{
var style = (ControlStyle)value;
var dictionary = new Dictionary<string, object> { [_typeProperty] = style.TargetType.Name };
foreach (var keyValuePair in style)
dictionary.Add(keyValuePair.Key, keyValuePair.Value);
JsonSerializer.Serialize(writer, dictionary);
}
}
}
@@ -1,38 +0,0 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Xna.Framework.Content;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Serialization;
namespace MonoGame.Extended.Gui.Serialization;
public static class GuiJsonSerializerOptionsProvider
{
public static JsonSerializerOptions GetOptions(ContentManager contentManager, params Type[] customControlTypes)
{
var options = new JsonSerializerOptions
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var textureRegionService = new GuiTextureRegionService();
options.Converters.Add(new Vector2JsonConverter());
options.Converters.Add(new SizeJsonConverter());
options.Converters.Add(new Size2JsonConverter());
options.Converters.Add(new ColorJsonConverter());
options.Converters.Add(new ThicknessJsonConverter());
options.Converters.Add(new ContentManagerJsonConverter<BitmapFont>(contentManager, font => font.Face));
options.Converters.Add(new ControlStyleJsonConverter(customControlTypes));
options.Converters.Add(new GuiTextureAtlasJsonConverter(contentManager, textureRegionService));
options.Converters.Add(new GuiNinePatchRegion2DJsonConverter(textureRegionService));
options.Converters.Add(new TextureRegion2DJsonConverter(textureRegionService));
options.Converters.Add(new VerticalAlignmentConverter());
options.Converters.Add(new HorizontalAlignmentConverter());
return options;
}
}
@@ -1,15 +0,0 @@
using MonoGame.Extended.Serialization;
namespace MonoGame.Extended.Gui.Serialization
{
public class GuiNinePatchRegion2DJsonConverter : NinePatchJsonConverter
{
private readonly IGuiTextureRegionService _textureRegionService;
public GuiNinePatchRegion2DJsonConverter(IGuiTextureRegionService textureRegionService)
: base(textureRegionService)
{
_textureRegionService = textureRegionService;
}
}
}
@@ -1,31 +0,0 @@
using System;
using System.Text.Json;
using Microsoft.Xna.Framework.Content;
using MonoGame.Extended.Graphics;
using MonoGame.Extended.Serialization;
namespace MonoGame.Extended.Gui.Serialization
{
public class GuiTextureAtlasJsonConverter : ContentManagerJsonConverter<Texture2DAtlas>
{
private readonly IGuiTextureRegionService _textureRegionService;
public GuiTextureAtlasJsonConverter(ContentManager contentManager, IGuiTextureRegionService textureRegionService)
: base(contentManager, atlas => atlas.Name)
{
_textureRegionService = textureRegionService;
}
/// <inheritdoc />
public override Texture2DAtlas Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var textureAtlas = base.Read(ref reader, typeToConvert, options);
if (textureAtlas is not null)
{
_textureRegionService.TextureAtlases.Add(textureAtlas);
}
return textureAtlas;
}
}
}
@@ -1,15 +0,0 @@
using System.Collections.Generic;
using MonoGame.Extended.Graphics;
using MonoGame.Extended.Serialization;
namespace MonoGame.Extended.Gui.Serialization
{
public interface IGuiTextureRegionService : ITextureRegionService
{
IList<Texture2DAtlas> TextureAtlases { get; }
}
public class GuiTextureRegionService : TextureRegionService, IGuiTextureRegionService
{
}
}
@@ -1,32 +0,0 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MonoGame.Extended.Gui.Serialization;
public class HorizontalAlignmentConverter : JsonConverter<HorizontalAlignment>
{
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(HorizontalAlignment);
/// <inheritdoc />
public override HorizontalAlignment Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if (value.Equals("Center", StringComparison.OrdinalIgnoreCase) || value.Equals("Centre", StringComparison.OrdinalIgnoreCase))
{
return HorizontalAlignment.Centre;
}
if (Enum.TryParse<HorizontalAlignment>(value, true, out var alignment))
{
return alignment;
}
throw new InvalidOperationException($"Invalid value for '{nameof(HorizontalAlignment)}'");
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, HorizontalAlignment value, JsonSerializerOptions options) { }
}
@@ -1,57 +0,0 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
namespace MonoGame.Extended.Gui.Serialization;
public interface IGuiSkinService
{
Skin Skin { get; set; }
}
public class SkinService : IGuiSkinService
{
public Skin Skin { get; set; }
}
public class SkinJsonConverter : JsonConverter<Skin>
{
private readonly ContentManager _contentManager;
private readonly IGuiSkinService _skinService;
private readonly Type[] _customControlTypes;
public SkinJsonConverter(ContentManager contentManager, IGuiSkinService skinService, params Type[] customControlTypes)
{
_contentManager = contentManager;
_skinService = skinService;
_customControlTypes = customControlTypes;
}
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Skin);
/// <inheritdoc />
public override Skin Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var assetName = reader.GetString();
// TODO: Load this using the ContentManager instead.
using (var stream = TitleContainer.OpenStream(assetName))
{
var skin = Skin.FromStream(_contentManager, stream, _customControlTypes);
_skinService.Skin = skin;
return skin;
}
}
throw new InvalidOperationException($"{nameof(SkinJsonConverter)} can only convert from a string");
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, Skin value, JsonSerializerOptions options) { }
}
@@ -1,32 +0,0 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MonoGame.Extended.Gui.Serialization;
public class VerticalAlignmentConverter : JsonConverter<VerticalAlignment>
{
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(VerticalAlignment);
/// <inheritdoc />
public override VerticalAlignment Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if (value.Equals("Center", StringComparison.OrdinalIgnoreCase) || value.Equals("Centre", StringComparison.OrdinalIgnoreCase))
{
return VerticalAlignment.Centre;
}
if (Enum.TryParse<VerticalAlignment>(value, true, out var alignment))
{
return alignment;
}
throw new InvalidOperationException($"Invalid value for '{nameof(VerticalAlignment)}'");
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, VerticalAlignment value, JsonSerializerOptions options) { }
}
-221
View File
@@ -1,221 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Collections;
using MonoGame.Extended.Graphics;
using MonoGame.Extended.Gui.Controls;
using MonoGame.Extended.Gui.Serialization;
namespace MonoGame.Extended.Gui
{
public class Skin
{
public Skin()
{
TextureAtlases = new List<Texture2DAtlas>();
Fonts = new List<BitmapFont>();
NinePatches = new List<NinePatch>();
Styles = new KeyedCollection<string, ControlStyle>(s => s.Name ?? s.TargetType.Name);
}
[JsonPropertyOrder(0)]
public string Name { get; set; }
[JsonPropertyOrder(1)]
public IList<Texture2DAtlas> TextureAtlases { get; set; }
[JsonPropertyOrder(2)]
public IList<BitmapFont> Fonts { get; set; }
[JsonPropertyOrder(3)]
public IList<NinePatch> NinePatches { get; set; }
[JsonPropertyOrder(4)]
public BitmapFont DefaultFont => Fonts.FirstOrDefault();
[JsonPropertyOrder(5)]
public Cursor Cursor { get; set; }
[JsonPropertyOrder(6)]
public KeyedCollection<string, ControlStyle> Styles { get; private set; }
public ControlStyle GetStyle(string name)
{
if (Styles.TryGetValue(name, out var controlStyle))
return controlStyle;
return null;
}
public ControlStyle GetStyle(Type controlType)
{
return GetStyle(controlType.FullName);
}
public void Apply(Control control)
{
// TODO: This allocates memory on each apply because it needs to apply styles in reverse
var types = new List<Type>();
var controlType = control.GetType();
while (controlType != null)
{
types.Add(controlType);
controlType = controlType.GetTypeInfo().BaseType;
}
for (var i = types.Count - 1; i >= 0; i--)
{
var style = GetStyle(types[i]);
style?.Apply(control);
}
}
public static Skin FromFile(ContentManager contentManager, string path, params Type[] customControlTypes)
{
using (var stream = TitleContainer.OpenStream(path))
{
return FromStream(contentManager, stream, customControlTypes);
}
}
public static Skin FromStream(ContentManager contentManager, Stream stream, params Type[] customControlTypes)
{
var options = GuiJsonSerializerOptionsProvider.GetOptions(contentManager, customControlTypes);
return JsonSerializer.Deserialize<Skin>(stream, options);
}
public T Create<T>(string template, Action<T> onCreate)
where T : Control, new()
{
var control = new T();
GetStyle(template).Apply(control);
onCreate(control);
return control;
}
public Control Create(Type type, string template)
{
var control = (Control)Activator.CreateInstance(type);
if (template != null)
{
var style = GetStyle(template);
if (style != null)
style.Apply(control);
else
throw new FormatException($"invalid style {template} for control {type.Name}");
}
return control;
}
public static Skin Default { get; set; }
public static Skin CreateDefault(BitmapFont font)
{
Default = new Skin
{
Fonts = { font },
Styles =
{
new ControlStyle(typeof(Control)) {
{nameof(Control.BackgroundColor), new Color(51, 51, 55)},
{nameof(Control.BorderColor), new Color(67, 67, 70)},
{nameof(Control.BorderThickness), 1},
{nameof(Control.TextColor), new Color(241, 241, 241)},
{nameof(Control.Padding), new Thickness(5)},
{nameof(Control.DisabledStyle), new ControlStyle(typeof(Control)) {
{ nameof(Control.TextColor), new Color(78,78,80) }
}
}
},
new ControlStyle(typeof(LayoutControl)) {
{nameof(Control.BackgroundColor), Color.Transparent},
{nameof(Control.BorderColor), Color.Transparent },
{nameof(Control.BorderThickness), 0},
{nameof(Control.Padding), new Thickness(0)},
{nameof(Control.Margin), new Thickness(0)},
},
new ControlStyle(typeof(ComboBox)) {
{nameof(ComboBox.DropDownColor), new Color(71, 71, 75)},
{nameof(ComboBox.SelectedItemColor), new Color(0, 122, 204)},
{nameof(ComboBox.HorizontalTextAlignment), HorizontalAlignment.Left }
},
new ControlStyle(typeof(CheckBox))
{
{nameof(CheckBox.HorizontalTextAlignment), HorizontalAlignment.Left },
{nameof(CheckBox.BorderThickness), 0},
{nameof(CheckBox.BackgroundColor), Color.Transparent},
},
new ControlStyle(typeof(ListBox))
{
{nameof(ListBox.SelectedItemColor), new Color(0, 122, 204)},
{nameof(ListBox.HorizontalTextAlignment), HorizontalAlignment.Left }
},
new ControlStyle(typeof(Label)) {
{nameof(Label.BackgroundColor), Color.Transparent},
{nameof(Label.TextColor), Color.White},
{nameof(Label.BorderColor), Color.Transparent},
{nameof(Label.BorderThickness), 0},
{nameof(Label.HorizontalTextAlignment), HorizontalAlignment.Left},
{nameof(Label.VerticalTextAlignment), VerticalAlignment.Bottom},
{nameof(Control.Margin), new Thickness(5,0)},
{nameof(Control.Padding), new Thickness(0)},
},
new ControlStyle(typeof(TextBox)) {
{nameof(Control.BackgroundColor), Color.DarkGray},
{nameof(Control.TextColor), Color.Black},
{nameof(Control.BorderColor), new Color(67, 67, 70)},
{nameof(Control.BorderThickness), 2},
},
new ControlStyle(typeof(TextBox2)) {
{nameof(Control.BackgroundColor), Color.DarkGray},
{nameof(Control.TextColor), Color.Black},
{nameof(Control.BorderColor), new Color(67, 67, 70)},
{nameof(Control.BorderThickness), 2},
},
new ControlStyle(typeof(Button)) {
{
nameof(Button.HoverStyle), new ControlStyle {
{nameof(Button.BackgroundColor), new Color(62, 62, 64)},
{nameof(Button.BorderColor), Color.WhiteSmoke }
}
},
{
nameof(Button.PressedStyle), new ControlStyle {
{nameof(Button.BackgroundColor), new Color(0, 122, 204)}
}
}
},
new ControlStyle(typeof(ToggleButton)) {
{
nameof(ToggleButton.CheckedStyle), new ControlStyle {
{nameof(Button.BackgroundColor), new Color(0, 122, 204)}
}
},
{
nameof(ToggleButton.CheckedHoverStyle), new ControlStyle {
{nameof(Button.BorderColor), Color.WhiteSmoke}
}
}
},
new ControlStyle(typeof(ProgressBar)) {
{nameof(ProgressBar.BarColor), new Color(0, 122, 204) },
{nameof(ProgressBar.Height), 32 },
{nameof(ProgressBar.Padding), new Thickness(5, 4)},
}
}
};
return Default;
}
}
}
-42
View File
@@ -1,42 +0,0 @@
using System;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Gui.Controls;
namespace MonoGame.Extended.Gui
{
//public class Window : Element<Screen>
//{
// public Window(Screen parent)
// {
// Parent = parent;
// }
// public ControlCollection Controls { get; } = new ControlCollection();
// public void Show()
// {
// Parent.Windows.Add(this);
// }
// public void Hide()
// {
// Parent.Windows.Remove(this);
// }
// public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
// {
// renderer.FillRectangle(BoundingRectangle, Color.Magenta);
// }
// public Size2 GetDesiredSize(IGuiContext context, Size2 availableSize)
// {
// return new Size2(Width, Height);
// }
// public void Layout(IGuiContext context, RectangleF rectangle)
// {
// foreach (var control in Controls)
// LayoutHelper.PlaceControl(context, control, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
// }
//}
}
@@ -1,10 +0,0 @@
namespace MonoGame.Extended.Gui
{
//public class WindowCollection : ElementCollection<Window, Screen>
//{
// public WindowCollection(Screen parent)
// : base(parent)
// {
// }
//}
}
@@ -1,122 +0,0 @@
//using System.Collections.Generic;
//using Microsoft.Xna.Framework.Graphics;
//using MonoGame.Extended.BitmapFonts;
//using MonoGame.Extended.Gui.Controls;
//using MonoGame.Extended.Tests;
//using MonoGame.Extended.TextureAtlases;
//using NSubstitute;
//using Xunit;
//namespace MonoGame.Extended.Gui.Tests.Controls
//{
// public class GuiButtonTests
// {
// [Fact]
// public void DesiredSizeShouldBeEmptyByDefault()
// {
// var availableSize = new Size2(800, 480);
// var context = Substitute.For<IGuiContext>();
// var button = new Button();
// var desiredSize = button.GetDesiredSize(context, availableSize);
// Assert.That(desiredSize, Is.EqualTo(Size2.Empty));
// }
// [Fact]
// public void DesiredSizeShouldBeTheSizeOfTheBackgroundRegion()
// {
// var availableSize = new Size2(800, 480);
// var context = Substitute.For<IGuiContext>();
// var backgroundRegion = MockTextureRegion();
// var button = new GuiButton { BackgroundRegion = backgroundRegion };
// var desiredSize = button.GetDesiredSize(context, availableSize);
// Assert.That(desiredSize, Is.EqualTo(backgroundRegion.Size));
// }
// [Fact]
// public void DesiredSizeShouldBeTheSizeOfTheMarginsInANinePatchRegion()
// {
// var availableSize = new Size2(800, 480);
// var context = Substitute.For<IGuiContext>();
// var texture = new Texture2D(new TestGraphicsDevice(), 512, 512);
// var backgroundRegion = new NinePatchRegion2D(new TextureRegion2D(texture), new Thickness(10, 20));
// var button = new GuiButton() { BackgroundRegion = backgroundRegion };
// var desiredSize = button.GetDesiredSize(context, availableSize);
// Assert.That(desiredSize, Is.EqualTo(new Size2(20, 40)));
// }
// [Fact]
// public void DesiredSizeShouldAtLeastBeTheSizeOfTheText()
// {
// const string text = "abcdefg";
// var availableSize = new Size2(800, 480);
// var context = Substitute.For<IGuiContext>();
// var font = CreateMockFont(text, lineHeight: 32);
// var expectedSize = font.MeasureString(text);
// var button = new GuiButton {Text = text, Font = font};
// var desiredSize = button.GetDesiredSize(context, availableSize);
// Assert.That(desiredSize, Is.EqualTo(expectedSize));
// }
// [Fact]
// public void DesiredSizeShouldAtLeastBeTheSizeOfTheIcon()
// {
// var texture = new Texture2D(new TestGraphicsDevice(), 35, 38);
// var icon = new TextureRegion2D(texture);
// var availableSize = new Size2(800, 480);
// var context = Substitute.For<IGuiContext>();
// var button = new GuiButton { IconRegion = icon };
// var desiredSize = button.GetDesiredSize(context, availableSize);
// Assert.That(desiredSize, Is.EqualTo(icon.Size));
// }
// [Fact]
// public void DesiredSizeShouldBeTheSizeOfTheBiggestTextOrIcon()
// {
// const string text = "abcdefg";
// var texture = new Texture2D(new TestGraphicsDevice(), 35, 38);
// var icon = new TextureRegion2D(texture);
// var iconExpectedSize = icon.Size;
// var availableSize = new Size2(800, 480);
// var context = Substitute.For<IGuiContext>();
// var font = CreateMockFont(text, 32);
// var fontExpectedSize = font.MeasureString(text);
// var button = new GuiButton { Text = text, Font = font, IconRegion = icon };
// var desiredSize = button.GetDesiredSize(context, availableSize);
// Assert.That(desiredSize.Width, Is.EqualTo(fontExpectedSize.Width));
// Assert.That(desiredSize.Height, Is.EqualTo(iconExpectedSize.Height));
// }
// private static BitmapFont CreateMockFont(string text, int lineHeight)
// {
// var regions = new List<BitmapFontRegion>();
// var xOffset = 0;
// foreach (var character in text)
// {
// regions.Add(new BitmapFontRegion(MockTextureRegion(10, 10), character, xOffset, yOffset: 0, xAdvance: 0));
// xOffset += 10;
// }
// return new BitmapFont("font", regions, lineHeight);
// }
// private static TextureRegion2D MockTextureRegion(int width = 100, int height = 200)
// {
// var texture = new Texture2D(new TestGraphicsDevice(), width, height);
// return new TextureRegion2D(texture, 0, 0, width, height);
// }
// }
//}
@@ -1,58 +0,0 @@
//using MonoGame.Extended.Gui.Controls;
//using NSubstitute;
//using Xunit;
//namespace MonoGame.Extended.Gui.Tests.Controls
//{
// public class GuiControlCollectionTests
// {
// [Fact]
// public void GuiControlCollection_Add_SetsTheParent_Test()
// {
// var parent = Substitute.For<GuiControl>();
// var child = Substitute.For<GuiControl>();
// var controls = new GuiControlCollection(parent) { child };
// Assert.IsTrue(controls.Contains(child));
// Assert.AreSame(parent, child.Parent);
// }
// [Fact]
// public void GuiControlCollection_Remove_SetsTheParentToNull_Test()
// {
// var parent = Substitute.For<GuiControl>();
// var child = Substitute.For<GuiControl>();
// new GuiControlCollection(parent) { child }.Remove(child);
// Assert.IsNull(child.Parent);
// }
// [Fact]
// public void GuiControlCollection_Insert_SetsTheParent_Test()
// {
// var parent = Substitute.For<GuiControl>();
// var child = Substitute.For<GuiControl>();
// var controls = new GuiControlCollection(parent);
// controls.Insert(0, child);
// Assert.IsTrue(controls.Contains(child));
// Assert.AreSame(parent, child.Parent);
// }
// [Fact]
// public void GuiControlCollection_Clear_SetsAllTheParentsToNull_Test()
// {
// var parent = Substitute.For<GuiControl>();
// var child0 = Substitute.For<GuiControl>();
// var child1 = Substitute.For<GuiControl>();
// new GuiControlCollection(parent) { child0, child1 }.Clear();
// Assert.IsNull(child0.Parent);
// Assert.IsNull(child1.Parent);
// }
// }
//}
@@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>$(DefineConstants);FNA</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\source\MonoGame.Extended.Gui\FNA.Extended.Gui.csproj" />
</ItemGroup>
</Project>
@@ -1,34 +0,0 @@
using MonoGame.Extended.Gui.Controls;
using Xunit;
namespace MonoGame.Extended.Gui.Tests
{
//
//public class GuiRendererTests
//{
// [Fact]
// public void GuiRenderer_TargetScreen_Test()
// {
// var screen = new GuiScreen();
// var renderer = new GuiTestRenderer(screen);
// Assert.That(renderer.TargetScreen, Is.SameAs(screen));
// }
//}
//public class GuiTestRenderer : GuiRenderer<TestDrawer>
//{
// public GuiTestRenderer(GuiScreen targetScreen)
// : base(targetScreen)
// {
// }
// protected override void DrawControl(TestDrawer drawer, GuiControl control)
// {
// }
//}
//public class TestDrawer
//{
//}
}
@@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>$(DefineConstants);KNI</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\source\MonoGame.Extended.Gui\KNI.Extended.Gui.csproj" />
</ItemGroup>
</Project>
@@ -1,7 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\source\MonoGame.Extended.Gui\MonoGame.Extended.Gui.csproj" />
</ItemGroup>
</Project>