diff --git a/.drone.yml b/.drone.yml index 5989617..9484e36 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,6 +11,7 @@ steps: - name: frontend image: privateregistry.michelescandura.com/michele/basecompileimage + pull: true volumes: - name: cache path: /release diff --git a/BaseCompileImage/Dockerfile b/BaseCompileImage/Dockerfile index db32cb0..b48f7c8 100644 --- a/BaseCompileImage/Dockerfile +++ b/BaseCompileImage/Dockerfile @@ -4,22 +4,42 @@ RUN export DEBIAN_FRONTEND=noninteractive \ && apt-get install -y --no-install-recommends \ wget \ ca-certificates \ - \ + gnupg \ + software-properties-common \ + p7zip-full \ + xvfb \ + curl \ # Install Microsoft package feed && wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \ && dpkg -i packages-microsoft-prod.deb \ - && rm packages-microsoft-prod.deb \ - \ + && rm packages-microsoft-prod.deb + # Install .NET - && apt-get update \ +RUN apt-get update \ && apt-get install -y --no-install-recommends \ - apt-transport-https \ + apt-transport-https \ dotnet-sdk-5.0 \ dotnet-sdk-3.1 \ libpng16-16 \ - libnvtt-dev \ - \ - # Cleanup - && rm -rf /var/lib/apt/lists/* + libnvtt-dev -RUN dotnet tool install -g dotnet-mgcb +RUN dpkg --add-architecture i386 +# && apt-get install --no-install-recommends -y gnupg software-properties-common p7zip-full xvfb curl + +RUN wget -qO- https://dl.winehq.org/wine-builds/winehq.key | apt-key add - \ + && apt-add-repository 'deb http://dl.winehq.org/wine-builds/ubuntu/ focal main' \ + && wget -qO- https://download.opensuse.org/repositories/Emulators:/Wine:/Debian/xUbuntu_18.04/Release.key | apt-key add - \ + && sh -c 'echo "deb https://download.opensuse.org/repositories/Emulators:/Wine:/Debian/xUbuntu_18.04/ ./" > /etc/apt/sources.list.d/obs.list' + +RUN apt-get update \ + && apt-get install --install-recommends -y winehq-stable + +RUN wget -qO- https://raw.githubusercontent.com/MonoGame/MonoGame/develop/Tools/MonoGame.Effect.Compiler/mgfxc_wine_setup.sh | xvfb-run sh + +RUN rm -rf /var/lib/apt/lists/* + +ENV MGFXC_WINE_PATH=/root/.winemonogame/ + +RUN apt-get remove -y xvfb p7zip-full gnupg curl \ + && apt-get autoremove -y \ + && apt-get autoclean -y diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.AllWidgets.exe b/External tools/Myra.1.0.3.213/Myra.Samples.AllWidgets.exe deleted file mode 100644 index 495e7bf..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.AllWidgets.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.AssetManagement.exe b/External tools/Myra.1.0.3.213/Myra.Samples.AssetManagement.exe deleted file mode 100644 index d8087be..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.AssetManagement.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.CustomUIStylesheet.exe b/External tools/Myra.1.0.3.213/Myra.Samples.CustomUIStylesheet.exe deleted file mode 100644 index 3448e83..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.CustomUIStylesheet.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.CustomWidgets.exe b/External tools/Myra.1.0.3.213/Myra.Samples.CustomWidgets.exe deleted file mode 100644 index 63f6309..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.CustomWidgets.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.DebugConsole.exe b/External tools/Myra.1.0.3.213/Myra.Samples.DebugConsole.exe deleted file mode 100644 index 08f4338..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.DebugConsole.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.GridContainer.exe b/External tools/Myra.1.0.3.213/Myra.Samples.GridContainer.exe deleted file mode 100644 index 815a06a..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.GridContainer.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.NonModalWindows.exe b/External tools/Myra.1.0.3.213/Myra.Samples.NonModalWindows.exe deleted file mode 100644 index 90a105b..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.NonModalWindows.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.Notepad.exe b/External tools/Myra.1.0.3.213/Myra.Samples.Notepad.exe deleted file mode 100644 index a884156..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.Notepad.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.ObjectEditor.exe b/External tools/Myra.1.0.3.213/Myra.Samples.ObjectEditor.exe deleted file mode 100644 index 6e2dbdb..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.ObjectEditor.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.Samples.SplitPaneContainer.exe b/External tools/Myra.1.0.3.213/Myra.Samples.SplitPaneContainer.exe deleted file mode 100644 index 0b98867..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.Samples.SplitPaneContainer.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/Myra.dll b/External tools/Myra.1.0.3.213/Myra.dll deleted file mode 100644 index 9644584..0000000 Binary files a/External tools/Myra.1.0.3.213/Myra.dll and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/MyraPad.exe b/External tools/Myra.1.0.3.213/MyraPad.exe deleted file mode 100644 index a1ae190..0000000 Binary files a/External tools/Myra.1.0.3.213/MyraPad.exe and /dev/null differ diff --git a/External tools/Myra.1.0.3.213/XNAssets.dll b/External tools/Myra.1.0.3.213/XNAssets.dll deleted file mode 100644 index ea84f69..0000000 Binary files a/External tools/Myra.1.0.3.213/XNAssets.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/AssetManagementBase.dll b/External tools/Myra.1.2.1.0/AssetManagementBase.dll new file mode 100644 index 0000000..f49a1cc Binary files /dev/null and b/External tools/Myra.1.2.1.0/AssetManagementBase.dll differ diff --git a/External tools/Myra.1.0.3.213/Assets/fonts/arial64.fnt b/External tools/Myra.1.2.1.0/Assets/fonts/arial64.fnt similarity index 100% rename from External tools/Myra.1.0.3.213/Assets/fonts/arial64.fnt rename to External tools/Myra.1.2.1.0/Assets/fonts/arial64.fnt diff --git a/External tools/Myra.1.0.3.213/Assets/fonts/arial64_0.png b/External tools/Myra.1.2.1.0/Assets/fonts/arial64_0.png similarity index 100% rename from External tools/Myra.1.0.3.213/Assets/fonts/arial64_0.png rename to External tools/Myra.1.2.1.0/Assets/fonts/arial64_0.png diff --git a/External tools/Myra.1.0.3.213/Assets/fonts/calibri32.fnt b/External tools/Myra.1.2.1.0/Assets/fonts/calibri32.fnt similarity index 100% rename from External tools/Myra.1.0.3.213/Assets/fonts/calibri32.fnt rename to External tools/Myra.1.2.1.0/Assets/fonts/calibri32.fnt diff --git a/External tools/Myra.1.0.3.213/Assets/fonts/calibri32_0.png b/External tools/Myra.1.2.1.0/Assets/fonts/calibri32_0.png similarity index 100% rename from External tools/Myra.1.0.3.213/Assets/fonts/calibri32_0.png rename to External tools/Myra.1.2.1.0/Assets/fonts/calibri32_0.png diff --git a/External tools/Myra.1.0.3.213/Assets/fonts/comicSans48.fnt b/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48.fnt similarity index 100% rename from External tools/Myra.1.0.3.213/Assets/fonts/comicSans48.fnt rename to External tools/Myra.1.2.1.0/Assets/fonts/comicSans48.fnt diff --git a/External tools/Myra.1.0.3.213/Assets/fonts/comicSans48_0.png b/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48_0.png similarity index 100% rename from External tools/Myra.1.0.3.213/Assets/fonts/comicSans48_0.png rename to External tools/Myra.1.2.1.0/Assets/fonts/comicSans48_0.png diff --git a/External tools/Myra.1.0.3.213/Assets/images/LogoOnly_64px.png b/External tools/Myra.1.2.1.0/Assets/images/LogoOnly_64px.png similarity index 100% rename from External tools/Myra.1.0.3.213/Assets/images/LogoOnly_64px.png rename to External tools/Myra.1.2.1.0/Assets/images/LogoOnly_64px.png diff --git a/External tools/Myra.1.2.1.0/Cyotek.Drawing.BitmapFont.dll b/External tools/Myra.1.2.1.0/Cyotek.Drawing.BitmapFont.dll new file mode 100644 index 0000000..c1ac309 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Cyotek.Drawing.BitmapFont.dll differ diff --git a/External tools/Myra.1.2.1.0/FontStashSharp.MonoGame.dll b/External tools/Myra.1.2.1.0/FontStashSharp.MonoGame.dll new file mode 100644 index 0000000..726576c Binary files /dev/null and b/External tools/Myra.1.2.1.0/FontStashSharp.MonoGame.dll differ diff --git a/External tools/Myra.1.0.3.213/MonoGame.Framework.dll b/External tools/Myra.1.2.1.0/MonoGame.Framework.dll similarity index 100% rename from External tools/Myra.1.0.3.213/MonoGame.Framework.dll rename to External tools/Myra.1.2.1.0/MonoGame.Framework.dll diff --git a/External tools/Myra.1.0.3.213/MonoGame.Framework.dll.config b/External tools/Myra.1.2.1.0/MonoGame.Framework.dll.config similarity index 100% rename from External tools/Myra.1.0.3.213/MonoGame.Framework.dll.config rename to External tools/Myra.1.2.1.0/MonoGame.Framework.dll.config diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.AllWidgets.exe b/External tools/Myra.1.2.1.0/Myra.Samples.AllWidgets.exe new file mode 100644 index 0000000..76d1d54 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.AllWidgets.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.AssetManagement.exe b/External tools/Myra.1.2.1.0/Myra.Samples.AssetManagement.exe new file mode 100644 index 0000000..d3fe2c1 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.AssetManagement.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.CustomUIStylesheet.exe b/External tools/Myra.1.2.1.0/Myra.Samples.CustomUIStylesheet.exe new file mode 100644 index 0000000..a07c836 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.CustomUIStylesheet.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.CustomWidgets.exe b/External tools/Myra.1.2.1.0/Myra.Samples.CustomWidgets.exe new file mode 100644 index 0000000..f9e4116 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.CustomWidgets.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.DebugConsole.exe b/External tools/Myra.1.2.1.0/Myra.Samples.DebugConsole.exe new file mode 100644 index 0000000..676ed3c Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.DebugConsole.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.GridContainer.exe b/External tools/Myra.1.2.1.0/Myra.Samples.GridContainer.exe new file mode 100644 index 0000000..3c75f3f Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.GridContainer.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.NonModalWindows.exe b/External tools/Myra.1.2.1.0/Myra.Samples.NonModalWindows.exe new file mode 100644 index 0000000..b86c9b5 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.NonModalWindows.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.Notepad.exe b/External tools/Myra.1.2.1.0/Myra.Samples.Notepad.exe new file mode 100644 index 0000000..ff20055 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.Notepad.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.ObjectEditor.exe b/External tools/Myra.1.2.1.0/Myra.Samples.ObjectEditor.exe new file mode 100644 index 0000000..379de96 Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.ObjectEditor.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.SplitPaneContainer.exe b/External tools/Myra.1.2.1.0/Myra.Samples.SplitPaneContainer.exe new file mode 100644 index 0000000..9e117cb Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.Samples.SplitPaneContainer.exe differ diff --git a/External tools/Myra.1.2.1.0/Myra.dll b/External tools/Myra.1.2.1.0/Myra.dll new file mode 100644 index 0000000..6681c3b Binary files /dev/null and b/External tools/Myra.1.2.1.0/Myra.dll differ diff --git a/External tools/Myra.1.2.1.0/MyraPad.exe b/External tools/Myra.1.2.1.0/MyraPad.exe new file mode 100644 index 0000000..a30dbf1 Binary files /dev/null and b/External tools/Myra.1.2.1.0/MyraPad.exe differ diff --git a/External tools/Myra.1.2.1.0/StbImageSharp.dll b/External tools/Myra.1.2.1.0/StbImageSharp.dll new file mode 100644 index 0000000..2e60d67 Binary files /dev/null and b/External tools/Myra.1.2.1.0/StbImageSharp.dll differ diff --git a/External tools/Myra.1.2.1.0/StbTrueTypeSharp.dll b/External tools/Myra.1.2.1.0/StbTrueTypeSharp.dll new file mode 100644 index 0000000..a3a030e Binary files /dev/null and b/External tools/Myra.1.2.1.0/StbTrueTypeSharp.dll differ diff --git a/External tools/Myra.1.0.3.213/Stylesheets/allControls.xmmp b/External tools/Myra.1.2.1.0/Stylesheets/allControls.xmmp similarity index 97% rename from External tools/Myra.1.0.3.213/Stylesheets/allControls.xmmp rename to External tools/Myra.1.2.1.0/Stylesheets/allControls.xmmp index 39785d1..3d9ffaa 100644 --- a/External tools/Myra.1.0.3.213/Stylesheets/allControls.xmmp +++ b/External tools/Myra.1.2.1.0/Stylesheets/allControls.xmmp @@ -1,4 +1,4 @@ - + diff --git a/External tools/Myra.1.0.3.213/Stylesheets/commodore-64/commodore-64.fnt b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/commodore-64.fnt similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/commodore-64/commodore-64.fnt rename to External tools/Myra.1.2.1.0/Stylesheets/commodore-64/commodore-64.fnt diff --git a/External tools/Myra.1.0.3.213/Stylesheets/commodore-64/ui_stylesheet.atlas b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.atlas similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/commodore-64/ui_stylesheet.atlas rename to External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.atlas diff --git a/External tools/Myra.1.0.3.213/Stylesheets/commodore-64/ui_stylesheet.xmms b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.xmms similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/commodore-64/ui_stylesheet.xmms rename to External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.xmms diff --git a/External tools/Myra.1.0.3.213/Stylesheets/commodore-64/ui_stylesheet_atlas.png b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet_atlas.png similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/commodore-64/ui_stylesheet_atlas.png rename to External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet_atlas.png diff --git a/External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_font.fnt b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_font.fnt similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_font.fnt rename to External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_font.fnt diff --git a/External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_stylesheet.atlas b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.atlas similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_stylesheet.atlas rename to External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.atlas diff --git a/External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_stylesheet.xmms b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.xmms similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_stylesheet.xmms rename to External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.xmms diff --git a/External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_stylesheet_atlas.png b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet_atlas.png similarity index 100% rename from External tools/Myra.1.0.3.213/Stylesheets/libgdx/ui_stylesheet_atlas.png rename to External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet_atlas.png diff --git a/External tools/Myra.1.0.3.213/image.png b/External tools/Myra.1.2.1.0/image.png similarity index 100% rename from External tools/Myra.1.0.3.213/image.png rename to External tools/Myra.1.2.1.0/image.png diff --git a/External tools/Myra.1.0.3.213/info.lundin.math.dll b/External tools/Myra.1.2.1.0/info.lundin.math.dll similarity index 100% rename from External tools/Myra.1.0.3.213/info.lundin.math.dll rename to External tools/Myra.1.2.1.0/info.lundin.math.dll diff --git a/External tools/Myra.1.0.3.213/libSDL2-2.0.0.dylib b/External tools/Myra.1.2.1.0/libSDL2-2.0.0.dylib similarity index 100% rename from External tools/Myra.1.0.3.213/libSDL2-2.0.0.dylib rename to External tools/Myra.1.2.1.0/libSDL2-2.0.0.dylib diff --git a/External tools/Myra.1.0.3.213/libopenal.1.dylib b/External tools/Myra.1.2.1.0/libopenal.1.dylib similarity index 100% rename from External tools/Myra.1.0.3.213/libopenal.1.dylib rename to External tools/Myra.1.2.1.0/libopenal.1.dylib diff --git a/Sledgemapper.Api/Commands/NewLineCommand.cs b/Sledgemapper.Api/Commands/NewLineCommand.cs new file mode 100644 index 0000000..3bfe3cf --- /dev/null +++ b/Sledgemapper.Api/Commands/NewLineCommand.cs @@ -0,0 +1,14 @@ +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Commands +{ + public class NewLineCommand : BaseCommand + { + public Line Line { get; private set; } + + public NewLineCommand(string sessionName, Line line, int userId) : base(sessionName, userId) + { + Line = line; + } + } +} diff --git a/Sledgemapper.Api/Commands/NewRoomCommand.cs b/Sledgemapper.Api/Commands/NewRoomCommand.cs new file mode 100644 index 0000000..5b7619e --- /dev/null +++ b/Sledgemapper.Api/Commands/NewRoomCommand.cs @@ -0,0 +1,14 @@ +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Commands +{ + public class NewRoomCommand : BaseCommand + { + public Room Room { get; private set; } + + public NewRoomCommand(string sessionName, Room room, int userId) : base(sessionName, userId) + { + Room = room; + } + } +} diff --git a/Sledgemapper.Api/Controllers/SessionController.cs b/Sledgemapper.Api/Controllers/SessionController.cs index 0ab3e32..2638ac5 100644 --- a/Sledgemapper.Api/Controllers/SessionController.cs +++ b/Sledgemapper.Api/Controllers/SessionController.cs @@ -60,6 +60,18 @@ namespace Sledgemapper.Api.Controllers await _mediator.Send(new NewNoteCommand(sessionName, note, UserId)); } + [HttpPost("room")] + public async Task Post(string sessionName, [FromBody] Room room) + { + await _mediator.Send(new NewRoomCommand(sessionName, room, UserId)); + } + + [HttpPost("line")] + public async Task Post(string sessionName, [FromBody] Line line) + { + await _mediator.Send(new NewLineCommand(sessionName, line, UserId)); + } + [HttpDelete("tile")] public async Task Delete(string sessionName, [FromBody] Tile tile) { diff --git a/Sledgemapper.Api/Handlers/NewLineCommandHandler.cs b/Sledgemapper.Api/Handlers/NewLineCommandHandler.cs new file mode 100644 index 0000000..4901dae --- /dev/null +++ b/Sledgemapper.Api/Handlers/NewLineCommandHandler.cs @@ -0,0 +1,39 @@ +using MediatR; +using Sledgemapper.Api.Data; +using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Commands; +using System.Linq; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Sledgemapper.Api.Notifications; + +namespace Sledgemapper.Api.Handlers +{ + public class NewLineCommandHandler : IRequestHandler + { + private readonly MyDbContext _dbcontext; + + private readonly IMediator _mediator; + + public NewLineCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } + + public async Task Handle(NewLineCommand notification, CancellationToken cancellationToken) + { + var jsonString = JsonSerializer.Serialize(notification.Line); + var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); + _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog + { + Operation = "N", + SessionId = session.SessionId, + Type = "L", + Timestamp = notification.Timestamp, + Object = jsonString, + UserId = notification.UserId, + }); + await _dbcontext.SaveChangesAsync(); + await _mediator.Publish(new NewLineNotification(session, notification.Line, notification.UserId)); + return true; + } + } +} diff --git a/Sledgemapper.Api/Handlers/NewNoteCommandHandler.cs b/Sledgemapper.Api/Handlers/NewNoteCommandHandler.cs new file mode 100644 index 0000000..5a50e45 --- /dev/null +++ b/Sledgemapper.Api/Handlers/NewNoteCommandHandler.cs @@ -0,0 +1,39 @@ +using MediatR; +using Sledgemapper.Api.Data; +using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Notifications; +using System.Linq; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +namespace Sledgemapper.Api.Handlers +{ + public class NewNoteCommandHandler : IRequestHandler + { + private readonly MyDbContext _dbcontext; + + private readonly IMediator _mediator; + + public NewNoteCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } + + public async Task Handle(NewNoteCommand notification, CancellationToken cancellationToken) + { + var jsonString = JsonSerializer.Serialize(notification.Note); + var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); + _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog + { + Operation = "N", + SessionId = session.SessionId, + Type = "N", + Timestamp = notification.Timestamp, + Object = jsonString, + UserId = notification.UserId, + }); + await _dbcontext.SaveChangesAsync(); + await _mediator.Publish(new NewNoteNotification(session, notification.Note, notification.UserId)); + return true; + } + } +} diff --git a/Sledgemapper.Api/Handlers/NewRoomCommandHandler.cs b/Sledgemapper.Api/Handlers/NewRoomCommandHandler.cs new file mode 100644 index 0000000..73561a1 --- /dev/null +++ b/Sledgemapper.Api/Handlers/NewRoomCommandHandler.cs @@ -0,0 +1,39 @@ +using MediatR; +using Sledgemapper.Api.Data; +using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Commands; +using System.Linq; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Sledgemapper.Api.Notifications; + +namespace Sledgemapper.Api.Handlers +{ + public class NewRoomCommandHandler : IRequestHandler + { + private readonly MyDbContext _dbcontext; + + private readonly IMediator _mediator; + + public NewRoomCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } + + public async Task Handle(NewRoomCommand notification, CancellationToken cancellationToken) + { + var jsonString = JsonSerializer.Serialize(notification.Room); + var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); + _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog + { + Operation = "N", + SessionId = session.SessionId, + Type = "R", + Timestamp = notification.Timestamp, + Object = jsonString, + UserId = notification.UserId, + }); + await _dbcontext.SaveChangesAsync(); + await _mediator.Publish(new NewRoomNotification(session, notification.Room, notification.UserId)); + return true; + } + } +} diff --git a/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs b/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs index a1a34ea..af69b69 100644 --- a/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs @@ -36,31 +36,4 @@ namespace Sledgemapper.Api.Handlers return true; } } - - public class NewNoteCommandHandler : IRequestHandler - { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public NewNoteCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(NewNoteCommand notification, CancellationToken cancellationToken) - { - var jsonString = JsonSerializer.Serialize(notification.Note); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "N", - SessionId = session.SessionId, - Type = "N", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId, - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new NewNoteNotification(session, notification.Note, notification.UserId)); - return true; - } - } } diff --git a/Sledgemapper.Api/Handlers/SendNewLineMessage.cs b/Sledgemapper.Api/Handlers/SendNewLineMessage.cs new file mode 100644 index 0000000..e0e9c86 --- /dev/null +++ b/Sledgemapper.Api/Handlers/SendNewLineMessage.cs @@ -0,0 +1,22 @@ +using MediatR; +using Microsoft.AspNetCore.SignalR; +using Sledgemapper.Api.Notifications; +using Sledgemapper.Clients; +using System.Threading; +using System.Threading.Tasks; +using Sledgemapper.Api.Hubs; + +namespace Sledgemapper.Api.Handlers +{ + public class SendNewLineMessage : INotificationHandler + { + private readonly IHubContext _hub; + + public SendNewLineMessage(IHubContext hub) => _hub = hub; + + public async Task Handle(NewLineNotification notification, CancellationToken cancellationToken) + { + await _hub.Clients.Groups(notification.Session.SessionName).NewLine(notification.Line); + } + } +} diff --git a/Sledgemapper.Api/Handlers/SendNewNoteMessage.cs b/Sledgemapper.Api/Handlers/SendNewNoteMessage.cs new file mode 100644 index 0000000..37e9f5a --- /dev/null +++ b/Sledgemapper.Api/Handlers/SendNewNoteMessage.cs @@ -0,0 +1,22 @@ +using MediatR; +using Microsoft.AspNetCore.SignalR; +using Sledgemapper.Api.Notifications; +using Sledgemapper.Clients; +using System.Threading; +using System.Threading.Tasks; +using Sledgemapper.Api.Hubs; + +namespace Sledgemapper.Api.Handlers +{ + public class SendNewNoteMessage : INotificationHandler + { + private readonly IHubContext _hub; + + public SendNewNoteMessage(IHubContext hub) => _hub = hub; + + public async Task Handle(NewNoteNotification notification, CancellationToken cancellationToken) + { + await _hub.Clients.Groups(notification.Session.SessionName).NewNote(notification.Note); + } + } +} diff --git a/Sledgemapper.Api/Handlers/SendNewRoomMessage.cs b/Sledgemapper.Api/Handlers/SendNewRoomMessage.cs new file mode 100644 index 0000000..adbf4ec --- /dev/null +++ b/Sledgemapper.Api/Handlers/SendNewRoomMessage.cs @@ -0,0 +1,22 @@ +using MediatR; +using Microsoft.AspNetCore.SignalR; +using Sledgemapper.Api.Notifications; +using Sledgemapper.Clients; +using System.Threading; +using System.Threading.Tasks; +using Sledgemapper.Api.Hubs; + +namespace Sledgemapper.Api.Handlers +{ + public class SendNewRoomMessage : INotificationHandler + { + private readonly IHubContext _hub; + + public SendNewRoomMessage(IHubContext hub) => _hub = hub; + + public async Task Handle(NewRoomNotification notification, CancellationToken cancellationToken) + { + await _hub.Clients.Groups(notification.Session.SessionName).NewRoom(notification.Room); + } + } +} diff --git a/Sledgemapper.Api/Handlers/SendNewWallMessage.cs b/Sledgemapper.Api/Handlers/SendNewWallMessage.cs index 699ff55..34d5567 100644 --- a/Sledgemapper.Api/Handlers/SendNewWallMessage.cs +++ b/Sledgemapper.Api/Handlers/SendNewWallMessage.cs @@ -19,16 +19,4 @@ namespace Sledgemapper.Api.Handlers await _hub.Clients.Groups(notification.Session.SessionName).NewWall(notification.Wall); } } - - public class SendNewNoteMessage : INotificationHandler - { - private readonly IHubContext _hub; - - public SendNewNoteMessage(IHubContext hub) => _hub = hub; - - public async Task Handle(NewNoteNotification notification, CancellationToken cancellationToken) - { - await _hub.Clients.Groups(notification.Session.SessionName).NewNote(notification.Note); - } - } } diff --git a/Sledgemapper.Api/Hubs/SledgemapperHub.cs b/Sledgemapper.Api/Hubs/SledgemapperHub.cs index 5cb91cd..c356461 100644 --- a/Sledgemapper.Api/Hubs/SledgemapperHub.cs +++ b/Sledgemapper.Api/Hubs/SledgemapperHub.cs @@ -46,6 +46,16 @@ namespace Sledgemapper.Api.Hubs await Clients.Group(sessionName).NewTile(tile); } + public async Task NewRoom(string sessionName, Room room) + { + await Clients.Group(sessionName).NewRoom(room); + } + + public async Task NewLine(string sessionName, Line line) + { + await Clients.Group(sessionName).NewLine(line); + } + public async Task NewWall(string sessionName, Wall tile) { await Clients.Group(sessionName).NewWall(tile); @@ -113,7 +123,7 @@ namespace Sledgemapper.Api.Hubs var userId = int.Parse(Context.User.Identity.Name); var SessionUsers = _dbContext.SessionUsers.Where(m => m.SessionId == sessionId).OrderBy(m => m.UserId).ToList(); var user = _datacontext.Users.First(u => u.Id == userId); - var player = new Player { UserId = userId, Initials = user.Initials, Position = tile, Color = UserColors[userId]}; + var player = new Player { UserId = userId, Initials = user.Initials, Position = tile, Color = UserColors[userId] }; await Clients.Group(sessionName).PlayerUpdate(player); } @@ -131,7 +141,7 @@ namespace Sledgemapper.Api.Hubs public override async Task OnDisconnectedAsync(Exception exception) { var userConnection = _dbContext.UserConnections.FirstOrDefault(m => m.ConnectionId == Context.ConnectionId); - var userId=userConnection.UserId; + var userId = userConnection.UserId; if (userConnection != null) { _dbContext.UserConnections.Remove(userConnection); @@ -142,8 +152,8 @@ namespace Sledgemapper.Api.Hubs foreach (var userSession in userSessions) { var session = _dbContext.Sessions.FirstOrDefault(m => m.SessionId == userSession.SessionId); - - await Clients.Group(session.SessionName).RemovePlayer(new Player{UserId=userId}); //send remove player + + await Clients.Group(session.SessionName).RemovePlayer(new Player { UserId = userId }); //send remove player _dbContext.SessionUsers.Remove(userSession); } } diff --git a/Sledgemapper.Api/Notifications/NewLineNotification.cs b/Sledgemapper.Api/Notifications/NewLineNotification.cs new file mode 100644 index 0000000..25c3005 --- /dev/null +++ b/Sledgemapper.Api/Notifications/NewLineNotification.cs @@ -0,0 +1,14 @@ +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Notifications +{ + public class NewLineNotification : BaseNotification + { + public Line Line { get; private set; } + + public NewLineNotification(Models.Session session, Line line, int userId) : base(session, userId) + { + Line = line; + } + } +} diff --git a/Sledgemapper.Api/Notifications/NewRoomNotification.cs b/Sledgemapper.Api/Notifications/NewRoomNotification.cs new file mode 100644 index 0000000..d83e27d --- /dev/null +++ b/Sledgemapper.Api/Notifications/NewRoomNotification.cs @@ -0,0 +1,14 @@ +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Notifications +{ + public class NewRoomNotification : BaseNotification + { + public Room Room { get; private set; } + + public NewRoomNotification(Models.Session session, Room room, int userId) : base(session, userId) + { + Room = room; + } + } +} diff --git a/Sledgemapper.Api/db/LocalDatabase.db b/Sledgemapper.Api/db/LocalDatabase.db new file mode 100644 index 0000000..22b8623 Binary files /dev/null and b/Sledgemapper.Api/db/LocalDatabase.db differ diff --git a/Sledgemapper.Api/db/sledgemapper.db b/Sledgemapper.Api/db/sledgemapper.db new file mode 100644 index 0000000..3991092 Binary files /dev/null and b/Sledgemapper.Api/db/sledgemapper.db differ diff --git a/Sledgemapper.Shared/Clients/ISledgemapperClient.cs b/Sledgemapper.Shared/Clients/ISledgemapperClient.cs index 2b51308..a1ec349 100644 --- a/Sledgemapper.Shared/Clients/ISledgemapperClient.cs +++ b/Sledgemapper.Shared/Clients/ISledgemapperClient.cs @@ -9,6 +9,7 @@ namespace Sledgemapper.Clients Task NewWall(Wall wall); Task NewOverlay(Overlay overlay); Task NewNote(Note note); + Task NewRoom(Room room); Task DeleteTile(Tile tile); Task DeleteNote(Note note); Task DeleteWall(Wall wall); @@ -18,5 +19,6 @@ namespace Sledgemapper.Clients Task RemovePlayer(Player player); Task UpdateMap(Session player); Task RefreshPlayers(); + Task NewLine(Line line); } } diff --git a/Sledgemapper.Shared/Entities/Session.cs b/Sledgemapper.Shared/Entities/Session.cs index ab1faa5..f9db985 100644 --- a/Sledgemapper.Shared/Entities/Session.cs +++ b/Sledgemapper.Shared/Entities/Session.cs @@ -27,6 +27,8 @@ namespace Sledgemapper.Shared.Entities Overlays = new ConcurrentDictionary(); Walls = new ConcurrentDictionary(); Notes = new ConcurrentDictionary(); + Lines=new ConcurrentDictionary(); + Rooms=new ConcurrentDictionary(); Players = new List(); Colors = new List(); } @@ -40,6 +42,8 @@ namespace Sledgemapper.Shared.Entities public List Colors { get; set; } public string SessionName { get; set; } public int SessionId { get; set; } + public ConcurrentDictionary Lines { get; private set; } + public ConcurrentDictionary Rooms { get; private set; } public void NewTile(Tile selectedTile, string tileId) { @@ -179,5 +183,45 @@ namespace Sledgemapper.Shared.Entities { MapEntityDeleted?.Invoke(this, e); } + + public void NewLine(Line line) + { + if (line is null) + { + return; + } + + var lineExist = Lines.TryGetValue(line.ToString(), out var tile); + var newLine = new Line { Start=line.Start, End=line.End, Width=line.Width}; + if (lineExist) + { + Lines.TryRemove(line.ToString(), out var _); + } + + Lines.TryAdd(newLine.ToString(), newLine); + + //TODO fix this + OnRaiseMapEntityAddedEvent(new MapEntityAddedEventArgs(newLine)); + } + + public void NewRoom(Room line) + { + if (line is null) + { + return; + } + + var lineExist = Rooms.TryGetValue(line.ToString(), out var tile); + var newLine = new Room { Start=line.Start, End=line.End, Delete=line.Delete}; + if (lineExist) + { + Rooms.TryRemove(line.ToString(), out var _); + } + + Rooms.TryAdd(newLine.ToString(), newLine); + + //TODO fix this + OnRaiseMapEntityAddedEvent(new MapEntityAddedEventArgs(newLine)); + } } } diff --git a/Sledgemapper.Shared/Entities/Tile.cs b/Sledgemapper.Shared/Entities/Tile.cs index 932da5a..aa0583f 100644 --- a/Sledgemapper.Shared/Entities/Tile.cs +++ b/Sledgemapper.Shared/Entities/Tile.cs @@ -1,21 +1,60 @@ -namespace Sledgemapper.Shared.Entities +using System; + +namespace Sledgemapper.Shared.Entities { - public abstract class BaseMapEntity - { - public int X { get; set; } + public abstract class BaseMapEntity + { + public BaseMapEntity() + { + Timestamp = DateTime.UtcNow.Ticks; + } + + public int X { get; set; } public int Y { get; set; } public string ID { get; set; } - public int Rotation { get; set; } - public override string ToString() + public int Rotation { get; set; } + public override string ToString() { return $"{X}_{Y}"; } - public double Timestamp {get;set;} - } + public double Timestamp { get; set; } + } - public class Tile :BaseMapEntity + public class Tile : BaseMapEntity { } - + public class Line : BaseMapEntity + { + public SnapPoint Start { get; set; } + public SnapPoint End { get; set; } + public float Width { get; set; } + + public override string ToString() + { + return $"{Start.X}_{Start.Y}_{Start.Index}_{End.X}_{End.Y}_{End.Index}"; + } + } + + public class Room : BaseMapEntity + { + public SnapPoint Start { get; set; } + public SnapPoint End { get; set; } + public bool Delete { get; set; } + + public override string ToString() + { + return $"{Start.X}_{Start.Y}_{Start.Index}_{End.X}_{End.Y}_{End.Index}"; + } + } + + public class SnapPoint : BaseMapEntity + { + public int Index { get; set; } + + public override string ToString() + { + return $"{X}_{Y}_{Index}"; + } + } } diff --git a/Sledgemapper/CommunicationManager.cs b/Sledgemapper/CommunicationManager.cs index a48e326..0fc37b6 100644 --- a/Sledgemapper/CommunicationManager.cs +++ b/Sledgemapper/CommunicationManager.cs @@ -95,6 +95,18 @@ namespace Sledgemapper SessionData.Map.TryAdd(tile.ToString(), tile); }); + Connection.On("NewRoom", (room) => + { + SessionData.Rooms.Remove(room.ToString(), out var _); + SessionData.Rooms.TryAdd(room.ToString(), room); + }); + + Connection.On("NewLine", (line) => + { + SessionData.Lines.Remove(line.ToString(), out var _); + SessionData.Lines.TryAdd(line.ToString(), line); + }); + Connection.On("RefreshPlayers", () => { if (!string.IsNullOrWhiteSpace(SessionData.SessionName)) @@ -166,7 +178,7 @@ namespace Sledgemapper { await Policy .Handle(ex => ex.StatusCode == HttpStatusCode.RequestTimeout) - + .RetryForeverAsync() //.RetryAsync(Polly.RetrySyntax., async (exception, retryCount) => await Task.Delay(500)) .ExecuteAsync(async () => await call().ConfigureAwait(false)) @@ -192,6 +204,12 @@ namespace Sledgemapper case Note note: Queue.Enqueue(async () => await Execute(async () => await Api.NewNote(note, SessionData.SessionName).ConfigureAwait(false))); break; + case Room room: + Queue.Enqueue(async () => await Execute(async () => await Api.NewRoom(room, SessionData.SessionName).ConfigureAwait(false))); + break; + case Line line: + Queue.Enqueue(async () => await Execute(async () => await Api.NewLine(line, SessionData.SessionName).ConfigureAwait(false))); + break; } break; diff --git a/Sledgemapper/Content/Content.mgcb b/Sledgemapper/Content/Content.mgcb index 95cf371..661c1e1 100644 --- a/Sledgemapper/Content/Content.mgcb +++ b/Sledgemapper/Content/Content.mgcb @@ -93,6 +93,42 @@ /processorParam:TextureFormat=Compressed /build:fonts/font99.spritefont +#begin icon_delete.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:icon_delete.png + +#begin icon_line.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:icon_line.png + +#begin icon_room.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:icon_room.png + #begin location.png /importer:TextureImporter /processor:TextureProcessor @@ -3021,6 +3057,18 @@ /processorParam:TextureFormat=Color /build:overlays/zigzag-hieroglyph.png +#begin shaders/OutlineShader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:shaders/OutlineShader.fx + +#begin shaders/OutlineShader2.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:shaders/OutlineShader2.fx + #begin tiles/tile01.png /importer:TextureImporter /processor:TextureProcessor diff --git a/Sledgemapper/Content/icon_delete.png b/Sledgemapper/Content/icon_delete.png new file mode 100644 index 0000000..ecec945 Binary files /dev/null and b/Sledgemapper/Content/icon_delete.png differ diff --git a/Sledgemapper/Content/icon_line.png b/Sledgemapper/Content/icon_line.png new file mode 100644 index 0000000..43004ec Binary files /dev/null and b/Sledgemapper/Content/icon_line.png differ diff --git a/Sledgemapper/Content/icon_room.png b/Sledgemapper/Content/icon_room.png new file mode 100644 index 0000000..a313a06 Binary files /dev/null and b/Sledgemapper/Content/icon_room.png differ diff --git a/Sledgemapper/Content/shaders/OutlineShader.fx b/Sledgemapper/Content/shaders/OutlineShader.fx new file mode 100644 index 0000000..3bc6bfe --- /dev/null +++ b/Sledgemapper/Content/shaders/OutlineShader.fx @@ -0,0 +1,88 @@ +#if OPENGL +#define SV_POSITION POSITION +#define VS_SHADERMODEL vs_3_0 +#define PS_SHADERMODEL ps_3_0 +#else +#define VS_SHADERMODEL vs_4_0_level_9_1 +#define PS_SHADERMODEL ps_4_0_level_9_1 +#endif +int BorderSize; +float R; +float G; +float B; +float2 ImageSize; + +sampler2D SpriteTextureSampler = sampler_state +{ + Texture = ; +}; + +struct VertexShaderOutput +{ + float4 Color : COLOR0; + float2 TextureCoordinates : TEXCOORD0; +}; + +float4 MainPS(VertexShaderOutput input) : COLOR +{ + float4 color = tex2Dlod(SpriteTextureSampler, float4(input.TextureCoordinates.x, input.TextureCoordinates.y, 0, 0)); + + if(color.a == 1) + { + return color; + } + + float2 pixel = (int2)input.TextureCoordinates * ImageSize; + + float2 offsets[8] = {float2(-1,0), float2(1,0), float2(0,1), float2(0,-1), float2(-1,1), float2(1,1), float2(1,-1), float2(-1,-1)}; + + float2 checkp1 = pixel + (float)BorderSize * offsets[0]; + float2 curUV1 = input.TextureCoordinates + checkp1/(float2)ImageSize; + float alpha1 = tex2Dlod(SpriteTextureSampler, float4(curUV1.x, curUV1.y,0,0)).a; + + float2 checkp2 = pixel + (float)BorderSize * offsets[1]; + float2 curUV2 = input.TextureCoordinates + checkp2/(float2)ImageSize; + float alpha2 = tex2Dlod(SpriteTextureSampler, float4(curUV2.x, curUV2.y,0,0)).a; + + float2 checkp3 = pixel + (float)BorderSize * offsets[2]; + float2 curUV3 = input.TextureCoordinates + checkp3/(float2)ImageSize; + float alpha3 = tex2Dlod(SpriteTextureSampler, float4(curUV3.x, curUV3.y,0,0)).a; + + float2 checkp4 = pixel + (float)BorderSize * offsets[3]; + float2 curUV4 = input.TextureCoordinates + checkp4/(float2)ImageSize; + float alpha4 = tex2Dlod(SpriteTextureSampler, float4(curUV4.x, curUV4.y,0,0)).a; + + float2 checkp5 = pixel + (float)BorderSize * offsets[4]; + float2 curUV5 = input.TextureCoordinates + checkp5/(float2)ImageSize; + float alpha5 = tex2Dlod(SpriteTextureSampler, float4(curUV5.x, curUV5.y,0,0)).a; + + float2 checkp6 = pixel + (float)BorderSize * offsets[5]; + float2 curUV6 = input.TextureCoordinates + checkp6/(float2)ImageSize; + float alpha6 = tex2Dlod(SpriteTextureSampler, float4(curUV6.x, curUV6.y,0,0)).a; + + float2 checkp7 = pixel + (float)BorderSize * offsets[6]; + float2 curUV7 = input.TextureCoordinates + checkp7/(float2)ImageSize; + float alpha7 = tex2Dlod(SpriteTextureSampler, float4(curUV7.x, curUV7.y,0,0)).a; + + float2 checkp8 = pixel + (float)BorderSize * offsets[7]; + float2 curUV8 = input.TextureCoordinates + checkp8/(float2)ImageSize; + float alpha8 = tex2Dlod(SpriteTextureSampler, float4(curUV8.x, curUV8.y,0,0)).a; + + float alpha = alpha1 + alpha2 + alpha3 + alpha4 + alpha5 + alpha6 + alpha7 + alpha8; + + if (alpha>0) + { + return float4(R,G,B,1); + } + +return color; + +}; + +technique SpriteDrawing +{ + pass P0 + { + PixelShader = compile PS_SHADERMODEL MainPS(); + } +}; \ No newline at end of file diff --git a/Sledgemapper/Content/shaders/OutlineShader2.fx b/Sledgemapper/Content/shaders/OutlineShader2.fx new file mode 100644 index 0000000..9479af2 --- /dev/null +++ b/Sledgemapper/Content/shaders/OutlineShader2.fx @@ -0,0 +1,209 @@ +/* ******************************************************** + * A Simple toon shader based on the work of Petri T. Wilhelmsen + * found on his blog post XNA Shader Programming � Tutorial 7, Toon shading + * http://digitalerr0r.wordpress.com/2009/03/22/xna-shader-programming-tutorial-7-toon-shading/. + * Which in turn is based on the shader "post edgeDetect" from nVidias Shader library + * http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html + * + * This process will use a Sobell convolution filter to determine contrast across each pixel. + * pixels that have a contrast greater than a given threshold value will be treated + * as an edge pixel and turned black. + * + * Author: John Marquiss + * Email: txg1152@gmail.com + * + * This work by John Marquiss is licensed under a + * Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. + * http://creativecommons.org/licenses/by-nc-sa/3.0/ + */ + +sampler ColorMapSampler : register(s0); + +/* Screen size (really texture size) is used to + * scale the outline line thickness nicely around the + * image + */ +float2 ScreenSize; + +/* Outline line thickness scale + */ +float Thickness = 1.0f; + +/* Edge detection threshold + * Contrast values over the threshold are considered + * edges. That means smaller values for the threshold make the + * image more "edgy" higher values less so. + */ +float Threshold = 0.0f; + +/* getGray + * a simple helper function to return a grey scale + * value for a given pixel + */ +float getGray(float4 c) +{ + /* The closer a color is to a pure gray + * value the closer its dot product and gray + * will be to 0. + */ + //return float4(1,1,1,1); + // if (c.a >0) + // { + // return float4(0,0,0,1); + // } + + // return float4(1,1,1,1); + return(dot(c.rgb,((0.33333).xxx))); +} + +struct VertexShaderOutput +{ + float2 Tex : TEXCOORD0; +}; + +/* Shade each pixel turning edge pixels black + */ +float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 +{ + // Get the source pixel color + float4 Color = tex2D(ColorMapSampler, input.Tex); + if (Color.a==0) + { + Color.rgba=0.8; + } + + /* ox is the X offset vector where the offest is based + * on the scaled edge thickness + */ + float2 ox = float2(Thickness/ScreenSize.x,0.0); + + /* oy is the Y offset vector where the offest is based + * on the scaled edge thickness + */ + float2 oy = float2(0.0,Thickness/ScreenSize.y); + + /* our current xy (uv) texture coordinate + */ + float2 uv = input.Tex.xy; + + /* Our kernel filter is a 3x3 matrix in order to process + * it we need to get the 8 neighbor pixles (top left, top, top right, + * left, right, bottom left, bottom, and bottom right) and the + * current pixel. For each of these pixels we then need to get + * its grey scale value using getGray. We will store the gray scale + * values in a 3x3 matrix g: + * g00 g01 g02 + * g10 g11 g12 + * g20 g21 g22 + */ + + /* First the bottom row pixels + * bottom left uv - oy - ox, bottom uv - oy and + * bottom right uv - oy + ox + */ + float2 PP = uv - oy; + float4 CC = tex2D(ColorMapSampler, PP-ox); float g00 = getGray(CC); + CC = tex2D(ColorMapSampler, PP); float g01 = getGray(CC); + CC = tex2D(ColorMapSampler, PP+ox); float g02 = getGray(CC); + + /* Next get the middle row pixels + * left uv - ox, current uv and right uv + ox + */ + PP = uv; + CC = tex2D(ColorMapSampler, PP-ox); float g10 = getGray(CC); + CC = tex2D(ColorMapSampler, PP); float g11 = getGray(CC); + CC = tex2D(ColorMapSampler, PP+ox); float g12 = getGray(CC); + + /* Finally get the top row pixels + * top left uv + oy - ox, top uv + oy and + * top right uv + oy + ox + */ + PP = uv + oy; + CC = tex2D(ColorMapSampler, PP-ox); float g20 = getGray(CC); + CC = tex2D(ColorMapSampler, PP); float g21 = getGray(CC); + CC = tex2D(ColorMapSampler, PP+ox); float g22 = getGray(CC); + + /* We will use a Sobell convolution filter + * -1 -2 -1 + * 0 0 0 + * 1 2 1 + */ + float K00 = -1; + float K01 = -2; + float K02 = -1; + float K10 = 0; + float K11 = 0; + float K12 = 0; + float K20 = 1; + float K21 = 2; + float K22 = 1; + + /* Calculate sx as the summation + * of g.ij * K.ij + * This will give us horizantal edge detection + */ + float sx = 0; + sx += g00 * K00; + sx += g01 * K01; + sx += g02 * K02; + sx += g10 * K10; + sx += g11 * K11; + sx += g12 * K12; + sx += g20 * K20; + sx += g21 * K21; + sx += g22 * K22; + + /* Calculate sy as the summation + * of g.ij * K.ji + * K.ji effectively rotates the kernel filter + * this will give us vertical edge detection + */ + float sy = 0; + sy += g00 * K00; + sy += g01 * K10; + sy += g02 * K20; + sy += g10 * K01; + sy += g11 * K11; + sy += g12 * K21; + sy += g20 * K02; + sy += g21 * K12; + sy += g22 * K22; + + /* Now merge the results of the horizantal + * and veritcal edge detection calculations + * together by calculating the distance of the + * vector they form. + */ + float contrast = sqrt(sx*sx + sy*sy); + + /* assume no edge (result = 1) + */ + float result = 1; + + /* If the length of s.xy has a value + * greater than the threshold then the color change (contrast) + * accoss that pixel is enough that we want to consider + * it an edge. Set result to 0 to black out that pixel. + */ + if (contrast > Threshold) + { + result = 0; + } + + /* finally return the original color multiplied + * by the result. For with contrast values over the + * threshold result will be 0 giving us a black edge. + * Make sure we do not clear out the alpha value though + * otherwise our edges will disappear if we use alpha + * blending. + */ + return Color*float4(contrast.xxx,1); +} + +technique PostOutline +{ + pass Pass0 + { + PixelShader = compile ps_2_0 PixelShaderFunction(); + } +} diff --git a/Sledgemapper/IMapApi.cs b/Sledgemapper/IMapApi.cs index 5b0ebc5..a68b3cd 100644 --- a/Sledgemapper/IMapApi.cs +++ b/Sledgemapper/IMapApi.cs @@ -49,5 +49,11 @@ namespace Sledgemapper [Headers("Authorization")] [Post("/users/authenticate")] Task Authenticate([Body] AuthenticateModel registerModel); + + [Post("/session/{sessionName}/room")] + Task NewRoom(Room room, string sessionName); + + [Post("/session/{sessionName}/line")] + Task NewLine(Line line, string sessionName); } } \ No newline at end of file diff --git a/Sledgemapper/InsertMode.cs b/Sledgemapper/InsertMode.cs index 5416f57..0081ecd 100644 --- a/Sledgemapper/InsertMode.cs +++ b/Sledgemapper/InsertMode.cs @@ -4,6 +4,11 @@ { Tile, Wall, - Overlay + Overlay, + NewWall, + NewLine, + NewRoom, + NewTile, + NewDelete } } diff --git a/Sledgemapper/Settings.cs b/Sledgemapper/Settings.cs index 343f071..25b39f6 100644 --- a/Sledgemapper/Settings.cs +++ b/Sledgemapper/Settings.cs @@ -11,6 +11,7 @@ namespace Sledgemapper public Color GridColor { get; set; } public Color NoteColor { get; set; } public string MachineName { get; set; } + public int TileDeleteDivider { get; set; } public Settings() { @@ -18,7 +19,7 @@ namespace Sledgemapper GridColor = Color.Black; NoteColor = Color.DarkRed; OverlayTintColor = new Color(24, 118, 157); - +TileDeleteDivider=14; try { MachineName = Environment.MachineName; diff --git a/Sledgemapper/Sledgemapper.cs b/Sledgemapper/Sledgemapper.cs index 8366f7c..ec8a885 100644 --- a/Sledgemapper/Sledgemapper.cs +++ b/Sledgemapper/Sledgemapper.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.SignalR.Client; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using MonoGame.Extended; using Myra; using Myra.Graphics2D.Brushes; using Myra.Graphics2D.TextureAtlases; @@ -39,6 +40,7 @@ namespace Sledgemapper private Texture2D _comment; private readonly Session _sessionData; private AuthenticateResponse _authResponse; + private RenderTarget2D rendertarget; private MainWidget _mainWidget; private bool _showCellNumbers; private readonly Settings _settings; @@ -76,7 +78,6 @@ namespace Sledgemapper _mainWidget.lblConnectionStatus.Text = "Reconnecting"; await Task.Yield(); } - private async Task OnHubReconnected(string arg) { ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Hub reconnected", Type = "SignalR Client Events", Source = _settings.MachineName }); @@ -89,9 +90,34 @@ namespace Sledgemapper ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Initialize", Type = "AppLifecycle", Source = _settings.MachineName }); IsMouseVisible = true; Window.AllowUserResizing = true; + Window.ClientSizeChanged += OnClientSizeChanged; + base.Initialize(); } + private void ResetRenderTarget() + { + rendertarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.DiscardContents); + + } + + private void OnClientSizeChanged(object sender, EventArgs e) + { + rendertarget?.Dispose(); + try + { + ResetRenderTarget(); + // rendertarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, true, SurfaceFormat.Alpha8, DepthFormat.Depth16, 0, RenderTargetUsage.DiscardContents); + //rendertarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height); + + } + catch + { + System.Console.WriteLine("rendertarget dispose exception"); + } + + } + private void AddItemToToolGrid(Grid grid, EventHandler eventAction, string folder) { var tilesFolderContent = Content.LoadContentFolder(folder); @@ -114,7 +140,11 @@ namespace Sledgemapper protected override void LoadContent() { _spriteBatch = new SpriteBatch(GraphicsDevice); + outlineShader = Content.Load("shaders/OutlineShader"); + outlineShader2 = Content.Load("shaders/OutlineShader2"); MyraEnvironment.Game = this; + ResetRenderTarget(); + // rendertarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, true, SurfaceFormat.Alpha8, DepthFormat.Depth16, 0, RenderTargetUsage.DiscardContents); _mainWidget = new MainWidget(); @@ -133,8 +163,16 @@ namespace Sledgemapper _mainWidget.MenuConnectJoin.Enabled = false; _mainWidget.MenuConnectSync.Enabled = false; _mainWidget.MenuConnectUpload.Enabled = false; + _mainWidget.BtnToolbarLine.Click += OnBtnToolbarLinClicked; + _mainWidget.BtnToolbarRoom.Click += OnBtnToolbarRoomClicked; + _mainWidget.BtnToolbarTile.Click += OnBtnToolbarTileClicked; + _mainWidget.BtnToolbarWall.Click += OnBtnToolbarWallClicked; + _mainWidget.BtnToolbarDelete.Click += OnBtnToolbarDeleteClicked; - AddItemToToolGrid(_mainWidget.GridTiles, OnTileButtonClicked, "tiles"); + + + _mainWidget.BtnToolbarTile.Visible = false; + _mainWidget.BtnToolbarWall.Visible = false; AddItemToToolGrid(_mainWidget.GridWalls, OnWallButtonClicked, "walls"); AddItemToToolGrid(_mainWidget.GridOverlays, OnOverlayButtonClicked, "overlays"); @@ -142,9 +180,38 @@ namespace Sledgemapper _eye = Content.Load("eye"); _location = Content.Load("location"); _comment = Content.Load("comment"); + _mainWidget.BtnToolbarLine.Image = new TextureRegion(Content.Load("icon_line")); + _mainWidget.BtnToolbarRoom.Image = new TextureRegion(Content.Load("icon_room")); + _mainWidget.BtnToolbarDelete.Image = new TextureRegion(Content.Load("icon_delete")); _desktop.Root = _mainWidget; } + private void OnBtnToolbarDeleteClicked(object sender, EventArgs e) + { + _state.InsertMode = InsertMode.NewDelete; + } + + private void OnBtnToolbarWallClicked(object sender, EventArgs e) + { + _state.InsertMode = InsertMode.NewWall; + } + + private void OnBtnToolbarTileClicked(object sender, EventArgs e) + { + _state.InsertMode = InsertMode.NewTile; + } + + private void OnBtnToolbarRoomClicked(object sender, EventArgs e) + { + _state.InsertMode = InsertMode.NewRoom; + + } + + private void OnBtnToolbarLinClicked(object sender, EventArgs e) + { + _state.InsertMode = InsertMode.NewLine; + } + private void OneMenuFileSettingsSelected(object sender, EventArgs e) { var propertyGrid = new PropertyGrid @@ -219,7 +286,6 @@ namespace Sledgemapper if (IsActive && GraphicsDevice.Viewport.Bounds.Contains(Mouse.GetState().Position) && !_desktop.IsMouseOverGUI && !_desktop.HasModalWidget) { - var mouseState = Mouse.GetState(); var screenPosition = new Point(mouseState.Position.X - (int)_viewportCenter.X, mouseState.Position.Y - (int)_viewportCenter.Y); @@ -246,10 +312,10 @@ namespace Sledgemapper _state.SelectOverlay(screenPosition); } - // if (newState.IsKeyDown(Keys.LeftControl) && newState.IsKeyDown(Keys.C) && !oldState.IsKeyDown(Keys.C)) - // { - // CenterOnSelectedTile(); - // } + if (_state.InsertMode == InsertMode.NewLine || _state.InsertMode == InsertMode.NewRoom || _state.InsertMode == InsertMode.NewDelete) + { + _state.SelectClosestSnapPoint(screenPosition); + } if (!newState.IsKeyDown(Keys.LeftControl) && mouseState.LeftButton == ButtonState.Pressed && mouseState.LeftButton == oldMouseState.LeftButton) { @@ -297,7 +363,6 @@ namespace Sledgemapper viewNoteButton.Click += OnContextMenuViewNoteClick; deleteNoteButton.Click += OnContextMenuDeleteNoteClick; - popup.AddChild(viewNoteButton); popup.AddChild(deleteNoteButton); } @@ -318,7 +383,6 @@ namespace Sledgemapper _sessionData.NewTile(_state.SelectedTile, _state.CurrentTileId); break; - case InsertMode.Wall: _sessionData.NewWall(_state.SelectedWall, _state.CurrentWallId); @@ -329,9 +393,94 @@ namespace Sledgemapper } } + + if (_state.InsertMode == InsertMode.NewLine && newState.IsKeyDown(Keys.LeftControl) + && mouseState.LeftButton == ButtonState.Released + && mouseState.LeftButton != oldMouseState.LeftButton) + { + if (_state.LineStart is null) + { + _state.LineStart = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }; + } + else + { + + var line = new Line + { + Start = new SnapPoint { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, + End = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }, + Width = _state.LineWidth + }; + _state.LineStart = null; + _state.LineWidth = 1; + _sessionData.NewLine(line); + } + } + + if (_state.InsertMode == InsertMode.NewRoom && newState.IsKeyDown(Keys.LeftControl) + && mouseState.LeftButton == ButtonState.Released + && mouseState.LeftButton != oldMouseState.LeftButton) + { + if (_state.LineStart is null) + { + _state.LineStart = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }; + } + else + { + + var line = new Room + { + Start = new SnapPoint { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, + End = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index } + }; + _state.LineStart = null; + _state.LineWidth = 1; + _sessionData.NewRoom(line); + } + + } + + + if (_state.InsertMode == InsertMode.NewDelete && newState.IsKeyDown(Keys.LeftControl) + && mouseState.LeftButton == ButtonState.Released + && mouseState.LeftButton != oldMouseState.LeftButton) + { + if (_state.LineStart is null) + { + _state.LineStart = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }; + } + else + { + + var line = new Room + { + Start = new SnapPoint { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, + End = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }, + Delete = true + }; + _state.LineStart = null; + _state.LineWidth = 1; + _sessionData.NewRoom(line); + } + + } + + if (_state.InsertMode == InsertMode.NewLine && _state.LineStart != null) + { + if (mouseState.ScrollWheelValue > oldMouseState.ScrollWheelValue) + { + _state.LineWidth += .01f; + } + else if (mouseState.ScrollWheelValue < oldMouseState.ScrollWheelValue) + { + _state.LineWidth -= .01f; + } + } + if (newState.IsKeyDown(Keys.LeftControl) && mouseState.ScrollWheelValue != oldMouseState.ScrollWheelValue) { // var center = new Point(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2); + var maxTileSize = 500; var center = new Point((Window.ClientBounds.Width + 200) / 2 - _state.TileSize / 2, Window.ClientBounds.Height / 2 - _state.TileSize / 2); var tx = (center.X - (int)_viewportCenter.X) / _state.TileSize; @@ -339,7 +488,7 @@ namespace Sledgemapper if (mouseState.ScrollWheelValue > oldMouseState.ScrollWheelValue) { - _state.TileSize = Math.Min(120, _state.TileSize + 10); + _state.TileSize = Math.Min(maxTileSize, _state.TileSize + 10); } else if (mouseState.ScrollWheelValue < oldMouseState.ScrollWheelValue) @@ -359,6 +508,9 @@ namespace Sledgemapper switch (_state.InsertMode) { case InsertMode.Tile: + case InsertMode.NewRoom: + case InsertMode.NewLine: + case InsertMode.NewDelete: _state.SelectedTile.X = _state.HoveredTile.X; _state.SelectedTile.Y = _state.HoveredTile.Y; _sessionData.DeleteTile(_state.SelectedTile); @@ -433,15 +585,68 @@ namespace Sledgemapper { return; } - GraphicsDevice.Clear(_settings.BackgroundColor); - var visibleTilesX = GraphicsDevice.Viewport.Width / _state.TileSize + 1; var visibleTilesY = GraphicsDevice.Viewport.Height / _state.TileSize + 1; - _spriteBatch.Begin(transformMatrix: Matrix.CreateTranslation(_viewportCenter)); + GraphicsDevice.SetRenderTarget(rendertarget); + _spriteBatch.Begin(depthStencilState: DepthStencilState.None, + transformMatrix: Matrix.CreateTranslation(_viewportCenter), + blendState: BlendState.Opaque, + //rasterizerState:RasterizerState.CullClockwise, + samplerState: SamplerState.PointClamp, + + sortMode: SpriteSortMode.Deferred); + + GraphicsDevice.Clear(Color.Transparent); + + foreach (var item in _sessionData.Lines.Values.Union(_sessionData.Rooms.Values).OrderBy(t => t.Timestamp)) + { + switch (item) + { + case Line l: + DrawLine(l); + break; + + case Room room: + if (room.Delete) + { + DrawDelete(room); + } + else + { + DrawRoom(room); + } + break; + } + } + + // + + _spriteBatch.End(); + + GraphicsDevice.SetRenderTarget(null); + + Vector2 texelSize = new Vector2((float)rendertarget.Width, (float)rendertarget.Height); + outlineShader.Parameters["ImageSize"].SetValue(texelSize); + outlineShader.Parameters["BorderSize"].SetValue((int)(_state.TileSize / 100f * 10f)); + + outlineShader.Parameters["R"].SetValue(_settings.OverlayTintColor.R / 255.0f); + outlineShader.Parameters["G"].SetValue(_settings.OverlayTintColor.G / 255.0f); + outlineShader.Parameters["B"].SetValue(_settings.OverlayTintColor.B / 255.0f); + // outlineShader2.Parameters["ScreenSize"].SetValue(texelSize); + _spriteBatch.Begin( + effect: outlineShader, + blendState: BlendState.NonPremultiplied, + sortMode: SpriteSortMode.Deferred); + GraphicsDevice.Clear(_settings.BackgroundColor); + _spriteBatch.Draw(rendertarget, Vector2.Zero, null, Color.White); + _spriteBatch.End(); + + _spriteBatch.Begin( + transformMatrix: Matrix.CreateTranslation(_viewportCenter), + sortMode: SpriteSortMode.Deferred); DrawTiles(); - DrawWalls(); DrawOverlays(); DrawNotes(); @@ -512,18 +717,200 @@ namespace Sledgemapper DrawPlayers(); - var startWall = new Vector2(_state.SelectedWall.X * _state.TileSize, _state.SelectedWall.Y * _state.TileSize); if (_state.InsertMode == InsertMode.Wall) { + var startWall = new Vector2(_state.SelectedWall.X * _state.TileSize, _state.SelectedWall.Y * _state.TileSize); _spriteBatch.DrawLine(startWall, _state.TileSize, MathHelper.ToRadians(90 * _state.SelectedWall.Rotation), Color.Red, 2); } - var overlay = new Vector2(_state.SelectedOverlay.X * _state.TileSize, _state.SelectedOverlay.Y * _state.TileSize); if (_state.InsertMode == InsertMode.Overlay && _state.SelectedOverlay.Intersection) { + var overlay = new Vector2(_state.SelectedOverlay.X * _state.TileSize, _state.SelectedOverlay.Y * _state.TileSize); _spriteBatch.DrawCircle(overlay, _state.TileSize / 3f, 100, Color.Red, 2); } + if (_state.InsertMode == InsertMode.NewLine && _state.SelectedSnapPoint != null) + { + var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize, _state.SelectedSnapPoint.Y * _state.TileSize); + + switch (_state.SelectedSnapPoint.Index) + { + case 1: + break; + case 2: + snapPoint.X += _state.TileSize / 2; + break; + case 3: + snapPoint.Y += _state.TileSize / 2; + break; + case 4: + snapPoint.Y += _state.TileSize / 2; + snapPoint.X += _state.TileSize / 2; + break; + } + + _spriteBatch.DrawCircle(snapPoint, _state.TileSize / 5f, 100, Color.Red, 2); + + + //line preview + if (_state.LineStart != null) + { + + // border pass + + // var content = Content.Load($"tiles/{tile.ID}"); + + var posX = _state.LineStart.X * _state.TileSize; + var posY = _state.LineStart.Y * _state.TileSize; + + var endposX = _state.SelectedSnapPoint.X * _state.TileSize; + var endposY = _state.SelectedSnapPoint.Y * _state.TileSize; + + switch (_state.LineStart.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (_state.SelectedSnapPoint.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + var l = Math.Sqrt(Math.Pow(posX - endposX, 2) + Math.Pow(posY - endposY, 2)); + + var angle = Math.Atan2(posY - endposY, endposX - posX); + var angleRad = -(float)angle;//MathHelper.ToRadians((float)angle); + if (l > 0) + { + var whiteRectangle = new Texture2D(GraphicsDevice, (int)l, (int)(_state.TileSize * _state.LineWidth)); + + whiteRectangle.SetData(Enumerable.Range(0, (int)l * ((int)(_state.TileSize * _state.LineWidth))).Select(i => new Color(Color.Red, 80)).ToArray()); + + _spriteBatch.Draw(whiteRectangle, new Rectangle(posX, posY, (int)l, (int)(_state.TileSize * _state.LineWidth)), null, Color.White, angleRad, new Vector2(0, 0), SpriteEffects.None, 1); + } + } + } + + if ((_state.InsertMode == InsertMode.NewRoom || _state.InsertMode == InsertMode.NewDelete) && _state.SelectedSnapPoint != null) + { + var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize, _state.SelectedSnapPoint.Y * _state.TileSize); + + switch (_state.SelectedSnapPoint.Index) + { + case 1: + break; + case 2: + snapPoint.X += _state.TileSize / 2; + break; + case 3: + snapPoint.Y += _state.TileSize / 2; + break; + case 4: + snapPoint.Y += _state.TileSize / 2; + snapPoint.X += _state.TileSize / 2; + break; + } + + _spriteBatch.DrawCircle(snapPoint, _state.TileSize / 6f, 50, Color.Red, 2); + + + //line preview + if (_state.LineStart != null) + { + var posX = _state.LineStart.X * _state.TileSize; + var posY = _state.LineStart.Y * _state.TileSize; + + var endposX = _state.SelectedSnapPoint.X * _state.TileSize; + var endposY = _state.SelectedSnapPoint.Y * _state.TileSize; + if (_state.InsertMode == InsertMode.NewDelete) + { + var ww = _state.TileSize / _settings.TileDeleteDivider; + if (posX == endposX) { endposX += ww; posX -= ww; } + if (posY == endposY) { endposY += ww; posY -= ww; } + } + switch (_state.LineStart.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (_state.SelectedSnapPoint.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + + if (posX != endposX && posY != endposY) + { + var whiteRectangle = new Texture2D(GraphicsDevice, 1, 1); + // whiteRectangle.SetData(new[] { new Color(Color.Red, 80) }); + whiteRectangle.SetData(new[] { new Color(Color.Red, 80) }); + if ((posX > endposX && posY > endposY) || (posX < endposX && posY < endposY)) + { + _spriteBatch.Draw(whiteRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 1); + } + else + { + if (endposY < posY) + { + _spriteBatch.Draw(whiteRectangle, new Rectangle(posX, endposY, endposX - posX, posY - endposY), null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 1); + } + + if (endposX < posX) + { + _spriteBatch.Draw(whiteRectangle, new Rectangle(endposX, posY, posX - endposX, endposY - posY), null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 1); + } + } + } + } + } _spriteBatch.End(); try @@ -764,8 +1151,51 @@ namespace Sledgemapper } + private int _borderWidth => (_state.TileSize / 6) % 2 == 0 ? (_state.TileSize / 6) : (_state.TileSize / 6) + 1; + private void DrawTiles() { + // foreach (var tile in _sessionData.Map.Values) + // { + // var content = Content.Load($"tiles/{tile.ID}"); + + // var posX = tile.X * _state.TileSize + _state.TileSize / 2f; + // var posY = tile.Y * _state.TileSize + _state.TileSize / 2f; + + // _spriteBatch.Draw(content, new Vector2(posX, posY), + // null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_state.TileSize) / content.Width, SpriteEffects.None, 0); + // } + + // border pass + // foreach (var tile in _sessionData.Map.Values) + // { + // var content = Content.Load($"tiles/{tile.ID}"); + + // var posX = tile.X * _state.TileSize; + // var posY = tile.Y * _state.TileSize; + + // var whiteRectangle = new Texture2D(GraphicsDevice, 1, 1); + // whiteRectangle.SetData(new[] { _settings.OverlayTintColor }); + + // _spriteBatch.Draw(whiteRectangle, new Rectangle((int)posX - _borderWidth / 2, (int)posY - _borderWidth / 2, _state.TileSize + _borderWidth, _state.TileSize + _borderWidth), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + // } + + //inner pass + // foreach (var tile in _sessionData.Map.Values) + // { + // var content = Content.Load($"tiles/{tile.ID}"); + + // var posX = tile.X * _state.TileSize; + // var posY = tile.Y * _state.TileSize; + + + // var whiteRectangle = new Texture2D(GraphicsDevice, 1, 1); + // whiteRectangle.SetData(new[] { Color.White }); + + // _spriteBatch.Draw(whiteRectangle, new Rectangle((int)posX, (int)posY, _state.TileSize, _state.TileSize), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + // } + + foreach (var tile in _sessionData.Map.Values) { var content = Content.Load($"tiles/{tile.ID}"); @@ -776,6 +1206,211 @@ namespace Sledgemapper _spriteBatch.Draw(content, new Vector2(posX, posY), null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_state.TileSize) / content.Width, SpriteEffects.None, 0); } + + } + private void DrawLine(Line tile) + { + var posX = tile.Start.X * _state.TileSize; + var posY = tile.Start.Y * _state.TileSize; + + var endposX = tile.End.X * _state.TileSize; + var endposY = tile.End.Y * _state.TileSize; + + switch (tile.Start.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (tile.End.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + var length = (int)Math.Sqrt(Math.Pow(posX - endposX, 2) + Math.Pow(posY - endposY, 2)); + var height = (int)(_state.TileSize * tile.Width); + if (length > 0) + { + var innerRectangle = new Texture2D(GraphicsDevice, 1, 1); + innerRectangle.SetData(new[] { Color.White }); + var angle = Math.Atan2(posY - endposY, endposX - posX); + var angleRad = -(float)angle; + _spriteBatch.Draw(innerRectangle, new Rectangle(posX, posY, length, height), null, Color.White, angleRad, new Vector2(0, 0), SpriteEffects.None, 1); + } + } + + + private void DrawRoom(Room tile) + { + var posX = tile.Start.X * _state.TileSize; + var posY = tile.Start.Y * _state.TileSize; + + var endposX = tile.End.X * _state.TileSize; + var endposY = tile.End.Y * _state.TileSize; + + switch (tile.Start.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (tile.End.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + if (posX != endposX && posY != endposY) + { + + var borderRectangle = new Texture2D(GraphicsDevice, 1, 1); + borderRectangle.SetData(new[] { Color.White }); + if ((posX < endposX && posY < endposY)) + + { + _spriteBatch.Draw(borderRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + else if ((posX > endposX && posY > endposY)) + { + _spriteBatch.Draw(borderRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + + else + { + if (endposY < posY) + { + _spriteBatch.Draw(borderRectangle, new Rectangle(posX, endposY, endposX - posX, posY - endposY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + + if (endposX < posX) + { + _spriteBatch.Draw(borderRectangle, new Rectangle(endposX, posY, posX - endposX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + } + } + } + Effect outlineShader; // Outline shader effect + private Effect outlineShader2; + + private void DrawDelete(Room tile) + { + var posX = tile.Start.X * _state.TileSize; + var posY = tile.Start.Y * _state.TileSize; + + var endposX = tile.End.X * _state.TileSize; + var endposY = tile.End.Y * _state.TileSize; + + + var ww = _state.TileSize / _settings.TileDeleteDivider; + if (posX == endposX) { endposX += ww; posX -= ww; } + if (posY == endposY) { endposY += ww; posY -= ww; } + switch (tile.Start.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (tile.End.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + if (posX != endposX && posY != endposY) + { + + var borderRectangle = new Texture2D(GraphicsDevice, 1, 1); + borderRectangle.SetData(new[] { Color.Transparent }); + if ((posX < endposX && posY < endposY)) + + { + _spriteBatch.Draw(borderRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + else if ((posX > endposX && posY > endposY)) + { + _spriteBatch.Draw(borderRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + + else + { + if (endposY < posY) + { + _spriteBatch.Draw(borderRectangle, new Rectangle(posX, endposY, endposX - posX, posY - endposY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + + if (endposX < posX) + { + _spriteBatch.Draw(borderRectangle, new Rectangle(endposX, posY, posX - endposX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + } + } } private void DrawWalls() @@ -1166,15 +1801,6 @@ namespace Sledgemapper _state.InsertMode = InsertMode.Overlay; } - private void OnTileButtonClicked(object sender, EventArgs e) - { - _state.CurrentTileId = ((ImageButton)sender).Id; - _mainWidget.ClearSelection(); - ((ImageButton)sender).Border = new SolidBrush(Color.Red); - ((ImageButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); - _state.InsertMode = InsertMode.Tile; - } - private void OnWallButtonClicked(object sender, EventArgs e) { _state.CurrentWallId = ((ImageButton)sender).Id; diff --git a/Sledgemapper/Sledgemapper.csproj b/Sledgemapper/Sledgemapper.csproj index 11c2001..f46b757 100644 --- a/Sledgemapper/Sledgemapper.csproj +++ b/Sledgemapper/Sledgemapper.csproj @@ -44,12 +44,13 @@ + 5.0.0 - + diff --git a/Sledgemapper/State.cs b/Sledgemapper/State.cs index 5e85745..d03d93b 100644 --- a/Sledgemapper/State.cs +++ b/Sledgemapper/State.cs @@ -1,6 +1,7 @@ using Microsoft.Xna.Framework; using System; using Sledgemapper.Shared.Entities; +using System.Collections.Generic; namespace Sledgemapper { @@ -10,11 +11,15 @@ namespace Sledgemapper public Tile HoveredTile { get; set; } public Wall SelectedWall { get; set; } public Overlay SelectedOverlay { get; set; } + public SnapPoint SelectedSnapPoint { get; set; } public Note SelectedNote { get; set; } public int TileSize { get; set; } public string CurrentTileId { get; set; } public string CurrentWallId { get; set; } public string CurrentOverlayId { get; set; } + public SnapPoint LineStart { get; internal set; } + public float LineWidth { get; internal set; } + public InsertMode InsertMode; public State() @@ -28,6 +33,7 @@ namespace Sledgemapper SelectedOverlay = new() { X = 1, Y = 1 }; SelectedNote = new() { X = 1, Y = 1 }; TileSize = 30; + LineWidth=1; } public void SelectClosestWall(Point mousePosition) @@ -63,6 +69,56 @@ namespace Sledgemapper SelectedWall.Rotation = 0; } } + + public bool CheckDistance(Point p1, Point p2, float d) + { + return ((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)) < d * d; + } + + + public void SelectClosestSnapPoint(Point mousePosition) + { + var distance = TileSize / 4; + + if (CheckDistance(mousePosition, new Point(HoveredTile.X * TileSize, HoveredTile.Y * TileSize), distance)) //x y + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X, Y = HoveredTile.Y, Index = 1 }; + } + else if (CheckDistance(mousePosition, new Point(HoveredTile.X * TileSize + TileSize / 2, HoveredTile.Y * TileSize + TileSize / 2), distance)) // x+1/2, y+1/2 + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X, Y = HoveredTile.Y, Index = 4 }; + } + else if (CheckDistance(mousePosition, new Point((HoveredTile.X + 1) * TileSize, HoveredTile.Y * TileSize), distance)) //x+1,y + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X + 1, Y = HoveredTile.Y, Index = 1 }; + } + else if (CheckDistance(mousePosition, new Point((HoveredTile.X + 1) * TileSize, (HoveredTile.Y + 1) * TileSize), distance)) //x+1, y+1 + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X + 1, Y = HoveredTile.Y + 1, Index = 1 }; + } + else if (CheckDistance(mousePosition, new Point((HoveredTile.X) * TileSize, (HoveredTile.Y + 1) * TileSize), distance))//x,y+1 + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X, Y = HoveredTile.Y + 1, Index = 1 }; + } + else if (CheckDistance(mousePosition, new Point(HoveredTile.X * TileSize, HoveredTile.Y * TileSize + TileSize / 2), distance)) //x, x+1/2 + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X, Y = HoveredTile.Y, Index = 3 }; + } + else if (CheckDistance(mousePosition, new Point(HoveredTile.X * TileSize + TileSize / 2, HoveredTile.Y * TileSize ), distance)) // x+1/2,y + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X, Y = HoveredTile.Y, Index = 2 }; + } + else if (CheckDistance(mousePosition, new Point(HoveredTile.X * TileSize + TileSize, HoveredTile.Y * TileSize + TileSize / 2), distance)) // x+1/2, y+1/2 + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X+1, Y = HoveredTile.Y, Index = 3 }; + } + else if (CheckDistance(mousePosition, new Point(HoveredTile.X * TileSize + TileSize / 2, HoveredTile.Y * TileSize + TileSize ), distance)) // x+1/2, y+1/2 + { + SelectedSnapPoint = new SnapPoint { X = HoveredTile.X, Y = HoveredTile.Y+1, Index = 2 }; + } + + + } public void SelectOverlay(Point mousePosition) { SelectedOverlay.X = HoveredTile.X; diff --git a/Sledgemapper/UI/MainWidget.Custom.cs b/Sledgemapper/UI/MainWidget.Custom.cs index 60734b2..34cb9fb 100644 --- a/Sledgemapper/UI/MainWidget.Custom.cs +++ b/Sledgemapper/UI/MainWidget.Custom.cs @@ -6,7 +6,6 @@ namespace Sledgemapper.UI { public void ClearSelection() { - ClearSelection(GridTiles); ClearSelection(GridWalls); ClearSelection(GridOverlays); } diff --git a/Sledgemapper/UI/MainWidget.Generated.cs b/Sledgemapper/UI/MainWidget.Generated.cs index 19c8773..2f730cd 100644 --- a/Sledgemapper/UI/MainWidget.Generated.cs +++ b/Sledgemapper/UI/MainWidget.Generated.cs @@ -1,15 +1,18 @@ -/* Generated by MyraPad at 02/12/2020 10:41:53 */ +/* Generated by MyraPad at 18/01/2021 09:38:43 */ using Myra; using Myra.Graphics2D; using Myra.Graphics2D.TextureAtlases; using Myra.Graphics2D.UI; using Myra.Graphics2D.Brushes; -#if !STRIDE +#if MONOGAME || FNA using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -#else +#elif STRIDE using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; #endif namespace Sledgemapper.UI @@ -124,30 +127,56 @@ namespace Sledgemapper.UI _mainMenu.Items.Add(menuItem2); _mainMenu.Items.Add(menuItem3); - GridTiles = new Grid(); - GridTiles.ColumnSpacing = 8; - GridTiles.RowSpacing = 8; - GridTiles.DefaultColumnProportion = new Proportion - { - Type = Myra.Graphics2D.UI.ProportionType.Pixels, - Value = 40, - }; - GridTiles.DefaultRowProportion = new Proportion - { - Type = Myra.Graphics2D.UI.ProportionType.Pixels, - Value = 40, - }; - GridTiles.Id = "GridTiles"; + BtnToolbarTile = new ImageTextButton(); + BtnToolbarTile.Text = " T"; + BtnToolbarTile.Width = 40; + BtnToolbarTile.Height = 40; + BtnToolbarTile.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + BtnToolbarTile.Id = "BtnToolbarTile"; - var scrollViewer1 = new ScrollViewer(); - scrollViewer1.Content = GridTiles; + BtnToolbarLine = new ImageTextButton(); + BtnToolbarLine.Text = " C"; + BtnToolbarLine.Width = 40; + BtnToolbarLine.Height = 40; + BtnToolbarLine.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + BtnToolbarLine.Id = "BtnToolbarLine"; - var verticalStackPanel1 = new VerticalStackPanel(); - verticalStackPanel1.Proportions.Add(new Proportion + BtnToolbarWall = new ImageTextButton(); + BtnToolbarWall.Text = " W"; + BtnToolbarWall.Width = 40; + BtnToolbarWall.Height = 40; + BtnToolbarWall.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + BtnToolbarWall.Id = "BtnToolbarWall"; + + BtnToolbarRoom = new ImageTextButton(); + BtnToolbarRoom.Text = " R"; + BtnToolbarRoom.Width = 40; + BtnToolbarRoom.Height = 40; + BtnToolbarRoom.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + BtnToolbarRoom.Id = "BtnToolbarRoom"; + + BtnToolbarDelete = new ImageTextButton(); + BtnToolbarDelete.Text = " D"; + BtnToolbarDelete.Width = 40; + BtnToolbarDelete.Height = 40; + BtnToolbarDelete.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + BtnToolbarDelete.Id = "BtnToolbarDelete"; + + var horizontalStackPanel1 = new HorizontalStackPanel(); + horizontalStackPanel1.Spacing = 5; + horizontalStackPanel1.Proportions.Add(new Proportion { - Type = Myra.Graphics2D.UI.ProportionType.Fill, + Type = Myra.Graphics2D.UI.ProportionType.Auto, }); - verticalStackPanel1.Widgets.Add(scrollViewer1); + horizontalStackPanel1.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + horizontalStackPanel1.Height = 51; + horizontalStackPanel1.Padding = new Thickness(4, 0, 0, 0); + horizontalStackPanel1.Background = new SolidBrush("#404040FF"); + horizontalStackPanel1.Widgets.Add(BtnToolbarTile); + horizontalStackPanel1.Widgets.Add(BtnToolbarLine); + horizontalStackPanel1.Widgets.Add(BtnToolbarWall); + horizontalStackPanel1.Widgets.Add(BtnToolbarRoom); + horizontalStackPanel1.Widgets.Add(BtnToolbarDelete); GridWalls = new Grid(); GridWalls.ColumnSpacing = 8; @@ -164,15 +193,15 @@ namespace Sledgemapper.UI }; GridWalls.Id = "GridWalls"; - var scrollViewer2 = new ScrollViewer(); - scrollViewer2.Content = GridWalls; + var scrollViewer1 = new ScrollViewer(); + scrollViewer1.Content = GridWalls; - var verticalStackPanel2 = new VerticalStackPanel(); - verticalStackPanel2.Proportions.Add(new Proportion + var verticalStackPanel1 = new VerticalStackPanel(); + verticalStackPanel1.Proportions.Add(new Proportion { Type = Myra.Graphics2D.UI.ProportionType.Fill, }); - verticalStackPanel2.Widgets.Add(scrollViewer2); + verticalStackPanel1.Widgets.Add(scrollViewer1); GridOverlays = new Grid(); GridOverlays.ColumnSpacing = 8; @@ -189,22 +218,21 @@ namespace Sledgemapper.UI }; GridOverlays.Id = "GridOverlays"; - var scrollViewer3 = new ScrollViewer(); - scrollViewer3.Content = GridOverlays; + var scrollViewer2 = new ScrollViewer(); + scrollViewer2.Content = GridOverlays; - var verticalStackPanel3 = new VerticalStackPanel(); - verticalStackPanel3.Proportions.Add(new Proportion + var verticalStackPanel2 = new VerticalStackPanel(); + verticalStackPanel2.Proportions.Add(new Proportion { Type = Myra.Graphics2D.UI.ProportionType.Fill, }); - verticalStackPanel3.Widgets.Add(scrollViewer3); + verticalStackPanel2.Widgets.Add(scrollViewer2); var verticalSplitPane1 = new VerticalSplitPane(); verticalSplitPane1.Width = 200; verticalSplitPane1.Background = new SolidBrush("#A1A1A1FF"); verticalSplitPane1.Widgets.Add(verticalStackPanel1); verticalSplitPane1.Widgets.Add(verticalStackPanel2); - verticalSplitPane1.Widgets.Add(verticalStackPanel3); var label1 = new Label(); label1.Text = "Connection status:"; @@ -234,22 +262,22 @@ namespace Sledgemapper.UI lblSessionName.MinWidth = 100; lblSessionName.Id = "lblSessionName"; - var horizontalStackPanel1 = new HorizontalStackPanel(); - horizontalStackPanel1.Spacing = 10; - horizontalStackPanel1.Proportions.Add(new Proportion + var horizontalStackPanel2 = new HorizontalStackPanel(); + horizontalStackPanel2.Spacing = 10; + horizontalStackPanel2.Proportions.Add(new Proportion { Type = Myra.Graphics2D.UI.ProportionType.Auto, }); - horizontalStackPanel1.Height = 25; - horizontalStackPanel1.Background = new SolidBrush("#333333FF"); - horizontalStackPanel1.Widgets.Add(label1); - horizontalStackPanel1.Widgets.Add(lblConnectionStatus); - horizontalStackPanel1.Widgets.Add(verticalSeparator1); - horizontalStackPanel1.Widgets.Add(label2); - horizontalStackPanel1.Widgets.Add(lblUsername); - horizontalStackPanel1.Widgets.Add(verticalSeparator2); - horizontalStackPanel1.Widgets.Add(label3); - horizontalStackPanel1.Widgets.Add(lblSessionName); + horizontalStackPanel2.Height = 25; + horizontalStackPanel2.Background = new SolidBrush("#333333FF"); + horizontalStackPanel2.Widgets.Add(label1); + horizontalStackPanel2.Widgets.Add(lblConnectionStatus); + horizontalStackPanel2.Widgets.Add(verticalSeparator1); + horizontalStackPanel2.Widgets.Add(label2); + horizontalStackPanel2.Widgets.Add(lblUsername); + horizontalStackPanel2.Widgets.Add(verticalSeparator2); + horizontalStackPanel2.Widgets.Add(label3); + horizontalStackPanel2.Widgets.Add(lblSessionName); Proportions.Add(new Proportion @@ -257,12 +285,17 @@ namespace Sledgemapper.UI Type = Myra.Graphics2D.UI.ProportionType.Auto, }); Proportions.Add(new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Auto, + }); + Proportions.Add(new Proportion { Type = Myra.Graphics2D.UI.ProportionType.Fill, }); Widgets.Add(_mainMenu); - Widgets.Add(verticalSplitPane1); Widgets.Add(horizontalStackPanel1); + Widgets.Add(verticalSplitPane1); + Widgets.Add(horizontalStackPanel2); } @@ -281,7 +314,11 @@ namespace Sledgemapper.UI public MenuItem MenuViewCenterOnSelection; public MenuItem MenuHelpAbout; public HorizontalMenu _mainMenu; - public Grid GridTiles; + public ImageTextButton BtnToolbarTile; + public ImageTextButton BtnToolbarLine; + public ImageTextButton BtnToolbarWall; + public ImageTextButton BtnToolbarRoom; + public ImageTextButton BtnToolbarDelete; public Grid GridWalls; public Grid GridOverlays; public Label lblConnectionStatus; diff --git a/Sledgemapper/UI/mainwidget.xml b/Sledgemapper/UI/mainwidget.xml index 2a727e1..0929de8 100644 --- a/Sledgemapper/UI/mainwidget.xml +++ b/Sledgemapper/UI/mainwidget.xml @@ -2,6 +2,7 @@ + @@ -31,18 +32,17 @@ + + + + + + + + + + - - - - - - - - - - -