Merge pull request 'develop' (#22) from develop into master

Reviewed-on: michele/Map#22
This commit is contained in:
michele 2021-01-18 14:55:06 +00:00
commit 94661cfb1b
89 changed files with 1576 additions and 154 deletions

View file

@ -11,6 +11,7 @@ steps:
- name: frontend
image: privateregistry.michelescandura.com/michele/basecompileimage
pull: true
volumes:
- name: cache
path: /release

View file

@ -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

Binary file not shown.

View file

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,4 +1,4 @@
<Project StylesheetPath="commodore-64/ui_stylesheet.xml">
<Project StylesheetPath="commodore-64/ui_stylesheet.xmms">
<ExportOptions Namespace="Myra.Samples.CustomUIStylesheet" Class="AllWidgets" OutputPath="D:\Projects\Hebron\Myra\Source\Samples\Myra.Samples.CustomUIStylesheet" />
<HorizontalSplitPane GridRow="1">
<ScrollPane>

View file

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Before After
Before After

View file

@ -0,0 +1,14 @@
using Sledgemapper.Shared.Entities;
namespace Sledgemapper.Api.Commands
{
public class NewLineCommand : BaseCommand<bool>
{
public Line Line { get; private set; }
public NewLineCommand(string sessionName, Line line, int userId) : base(sessionName, userId)
{
Line = line;
}
}
}

View file

@ -0,0 +1,14 @@
using Sledgemapper.Shared.Entities;
namespace Sledgemapper.Api.Commands
{
public class NewRoomCommand : BaseCommand<bool>
{
public Room Room { get; private set; }
public NewRoomCommand(string sessionName, Room room, int userId) : base(sessionName, userId)
{
Room = room;
}
}
}

View file

@ -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)
{

View file

@ -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<NewLineCommand, bool>
{
private readonly MyDbContext _dbcontext;
private readonly IMediator _mediator;
public NewLineCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; }
public async Task<bool> Handle(NewLineCommand notification, CancellationToken cancellationToken)
{
var jsonString = JsonSerializer.Serialize<Line>(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;
}
}
}

View file

@ -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<NewNoteCommand, bool>
{
private readonly MyDbContext _dbcontext;
private readonly IMediator _mediator;
public NewNoteCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; }
public async Task<bool> Handle(NewNoteCommand notification, CancellationToken cancellationToken)
{
var jsonString = JsonSerializer.Serialize<Note>(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;
}
}
}

View file

@ -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<NewRoomCommand, bool>
{
private readonly MyDbContext _dbcontext;
private readonly IMediator _mediator;
public NewRoomCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; }
public async Task<bool> Handle(NewRoomCommand notification, CancellationToken cancellationToken)
{
var jsonString = JsonSerializer.Serialize<Room>(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;
}
}
}

View file

@ -36,31 +36,4 @@ namespace Sledgemapper.Api.Handlers
return true;
}
}
public class NewNoteCommandHandler : IRequestHandler<NewNoteCommand, bool>
{
private readonly MyDbContext _dbcontext;
private readonly IMediator _mediator;
public NewNoteCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; }
public async Task<bool> Handle(NewNoteCommand notification, CancellationToken cancellationToken)
{
var jsonString = JsonSerializer.Serialize<Note>(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;
}
}
}

View file

@ -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<NewLineNotification>
{
private readonly IHubContext<SledgemapperHub, ISledgemapperClient> _hub;
public SendNewLineMessage(IHubContext<SledgemapperHub, ISledgemapperClient> hub) => _hub = hub;
public async Task Handle(NewLineNotification notification, CancellationToken cancellationToken)
{
await _hub.Clients.Groups(notification.Session.SessionName).NewLine(notification.Line);
}
}
}

View file

@ -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<NewNoteNotification>
{
private readonly IHubContext<SledgemapperHub, ISledgemapperClient> _hub;
public SendNewNoteMessage(IHubContext<SledgemapperHub, ISledgemapperClient> hub) => _hub = hub;
public async Task Handle(NewNoteNotification notification, CancellationToken cancellationToken)
{
await _hub.Clients.Groups(notification.Session.SessionName).NewNote(notification.Note);
}
}
}

View file

@ -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<NewRoomNotification>
{
private readonly IHubContext<SledgemapperHub, ISledgemapperClient> _hub;
public SendNewRoomMessage(IHubContext<SledgemapperHub, ISledgemapperClient> hub) => _hub = hub;
public async Task Handle(NewRoomNotification notification, CancellationToken cancellationToken)
{
await _hub.Clients.Groups(notification.Session.SessionName).NewRoom(notification.Room);
}
}
}

View file

@ -19,16 +19,4 @@ namespace Sledgemapper.Api.Handlers
await _hub.Clients.Groups(notification.Session.SessionName).NewWall(notification.Wall);
}
}
public class SendNewNoteMessage : INotificationHandler<NewNoteNotification>
{
private readonly IHubContext<SledgemapperHub, ISledgemapperClient> _hub;
public SendNewNoteMessage(IHubContext<SledgemapperHub, ISledgemapperClient> hub) => _hub = hub;
public async Task Handle(NewNoteNotification notification, CancellationToken cancellationToken)
{
await _hub.Clients.Groups(notification.Session.SessionName).NewNote(notification.Note);
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

Binary file not shown.

Binary file not shown.

View file

@ -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);
}
}

View file

@ -27,6 +27,8 @@ namespace Sledgemapper.Shared.Entities
Overlays = new ConcurrentDictionary<string, Overlay>();
Walls = new ConcurrentDictionary<string, Wall>();
Notes = new ConcurrentDictionary<string, Note>();
Lines=new ConcurrentDictionary<string, Line>();
Rooms=new ConcurrentDictionary<string, Room>();
Players = new List<Player>();
Colors = new List<string>();
}
@ -40,6 +42,8 @@ namespace Sledgemapper.Shared.Entities
public List<string> Colors { get; set; }
public string SessionName { get; set; }
public int SessionId { get; set; }
public ConcurrentDictionary<string, Line> Lines { get; private set; }
public ConcurrentDictionary<string, Room> 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));
}
}
}

View file

@ -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}";
}
}
}

View file

@ -95,6 +95,18 @@ namespace Sledgemapper
SessionData.Map.TryAdd(tile.ToString(), tile);
});
Connection.On<Room>("NewRoom", (room) =>
{
SessionData.Rooms.Remove(room.ToString(), out var _);
SessionData.Rooms.TryAdd(room.ToString(), room);
});
Connection.On<Line>("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<ApiException>(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;

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

View file

@ -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 = <SpriteTexture>;
};
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();
}
};

View file

@ -0,0 +1,209 @@
/* ********************************************************
* A Simple toon shader based on the work of Petri T. Wilhelmsen
* found on his blog post XNA Shader Programming <EFBFBD> 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();
}
}

View file

@ -49,5 +49,11 @@ namespace Sledgemapper
[Headers("Authorization")]
[Post("/users/authenticate")]
Task<AuthenticateResponse> Authenticate([Body] AuthenticateModel registerModel);
[Post("/session/{sessionName}/room")]
Task NewRoom(Room room, string sessionName);
[Post("/session/{sessionName}/line")]
Task NewLine(Line line, string sessionName);
}
}

View file

@ -4,6 +4,11 @@
{
Tile,
Wall,
Overlay
Overlay,
NewWall,
NewLine,
NewRoom,
NewTile,
NewDelete
}
}

View file

@ -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;

View file

@ -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<Texture2D>(folder);
@ -114,7 +140,11 @@ namespace Sledgemapper
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
outlineShader = Content.Load<Effect>("shaders/OutlineShader");
outlineShader2 = Content.Load<Effect>("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<Texture2D>("eye");
_location = Content.Load<Texture2D>("location");
_comment = Content.Load<Texture2D>("comment");
_mainWidget.BtnToolbarLine.Image = new TextureRegion(Content.Load<Texture2D>("icon_line"));
_mainWidget.BtnToolbarRoom.Image = new TextureRegion(Content.Load<Texture2D>("icon_room"));
_mainWidget.BtnToolbarDelete.Image = new TextureRegion(Content.Load<Texture2D>("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<BaseMapEntity>(_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<Texture2D>($"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<Texture2D>($"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<Texture2D>($"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<Texture2D>($"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<Texture2D>($"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;

View file

@ -44,12 +44,13 @@
<PackageReference Include="AsyncAwaitBestPractices" Version="5.0.2" />
<PackageReference Include="exceptionless" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
<PackageReference Include="MonoGame.Extended" Version="3.8.0" />
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.0.1641" />
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.0.1641" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client">
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Myra" Version="1.0.3.213" />
<PackageReference Include="Myra" Version="1.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="polly" Version="7.2.1" />
<PackageReference Include="polly.extensions.http" Version="3.0.0" />

View file

@ -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;

View file

@ -6,7 +6,6 @@ namespace Sledgemapper.UI
{
public void ClearSelection()
{
ClearSelection(GridTiles);
ClearSelection(GridWalls);
ClearSelection(GridOverlays);
}

View file

@ -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;

View file

@ -2,6 +2,7 @@
<Project.ExportOptions Namespace="Sledgemapper.UI" Class="MainWidget" OutputPath="C:\dev\Map\Sledgemapper\UI" />
<VerticalStackPanel>
<VerticalStackPanel.Proportions>
<Proportion Type="Auto" />
<Proportion Type="Auto" />
<Proportion Type="Fill" />
</VerticalStackPanel.Proportions>
@ -31,18 +32,17 @@
<MenuItem Text="&amp;About" Id="MenuHelpAbout" />
</MenuItem>
</HorizontalMenu>
<HorizontalStackPanel Spacing="5" VerticalAlignment="Center" Height="51" Padding="4, 0, 0, 0" Background="#404040FF">
<HorizontalStackPanel.Proportions>
<Proportion Type="Auto" />
</HorizontalStackPanel.Proportions>
<ImageTextButton Text=" T" Width="40" Height="40" VerticalAlignment="Center" Id="BtnToolbarTile" />
<ImageTextButton Text=" C" Width="40" Height="40" VerticalAlignment="Center" Id="BtnToolbarLine" />
<ImageTextButton Text=" W" Width="40" Height="40" VerticalAlignment="Center" Id="BtnToolbarWall" />
<ImageTextButton Text=" R" Width="40" Height="40" VerticalAlignment="Center" Id="BtnToolbarRoom" />
<ImageTextButton Text=" D" Width="40" Height="40" VerticalAlignment="Center" Id="BtnToolbarDelete" />
</HorizontalStackPanel>
<VerticalSplitPane Width="200" Background="#A1A1A1FF">
<VerticalStackPanel>
<VerticalStackPanel.Proportions>
<Proportion Type="Fill" />
</VerticalStackPanel.Proportions>
<ScrollViewer>
<Grid ColumnSpacing="8" RowSpacing="8" Id="GridTiles">
<Grid.DefaultColumnProportion Type="Pixels" Value="40" />
<Grid.DefaultRowProportion Type="Pixels" Value="40" />
</Grid>
</ScrollViewer>
</VerticalStackPanel>
<VerticalStackPanel>
<VerticalStackPanel.Proportions>
<Proportion Type="Fill" />