using System; using System.IO; using Microsoft.AspNetCore.SignalR.Client; using Microsoft.Xna.Framework; using Myra.Graphics2D; using Myra.Graphics2D.Brushes; using Myra.Graphics2D.UI; using Myra.Graphics2D.UI.File; using Myra.Graphics2D.UI.Properties; using Newtonsoft.Json; using Sledgemapper.Messages; using Sledgemapper.Shared.Entities; using TinyMessenger; namespace Sledgemapper.UI { public partial class MainWidget { private CommunicationManager CommunicationManager { get; } private TinyMessengerHub Messenger { get; } private GameWindow Window { get; } public MainWidget(CommunicationManager communicationManager, TinyMessengerHub messenger, GameWindow window) { BuildUI(); CommunicationManager = communicationManager; Window = window; Messenger = messenger; Messenger.Subscribe(OnLoginSuccesfulMessage); Messenger.Subscribe(OnSignalrConnectionUpdateMessage); Messenger.Subscribe(OnMapOpenedMessage); Messenger.Subscribe(OnCenterOnTileMessage); Messenger.Subscribe(OnCampaignSelectedMessage); Messenger.Subscribe(OnErrorMessage); MenuConnectLogin.Selected += OnMenuConnectLoginSelected; MenuConnectSync.Selected += OnMenuConnectSyncSelected; MenuFileLoad.Selected += OnMenuFileLoadSelected; MenuFileSave.Selected += OnMenuFileSaveSelected; MenuFileSettings.Selected += OneMenuFileSettingsSelected; //MenuConnectLogin.Selected += OnMenuConnectLoginSelected; //MenuConnectNew.Selected += OnMenuConnectNewSelected; //MenuConnectJoin.Selected += OnMenuConnectJoinSelected; MenuConnectUpload.Selected += OnMenuConnectUploadSelected; MenuViewCenterOnSelection.Selected += OnMenuViewCenterOnSelectionSelected; MenuViewShowCellNUmbers.Selected += OnMenuViewShowCellNUmbersSelected; MenuViewShowNotes.Selected += OnMenuViewNotesSelected; MenuCampaingNew.Selected += OnMenuCampaignNew; MenuCampaignOpen.Selected += OnMenuCampaignOpen; MenuCampaignPlayers.Selected += OnMenuCampaignPlayersSelected; MenuMapOpen.Selected += OnMenuMapOpen; MenuMapNew.Selected += OnMenuMapNew; //MenuConnectNew.Enabled = false; //MenuConnectJoin.Enabled = false; MenuConnectSync.Enabled = false; MenuConnectUpload.Enabled = false; MenuCampaignOpen.Enabled = false; MenuCampaignPlayers.Enabled = false; MenuCampaingNew.Enabled = false; MenuMapNew.Enabled = false; MenuMapOpen.Enabled = false; BtnToolbarLine.Click += OnBtnToolbarLinClicked; BtnToolbarRoom.Click += OnBtnToolbarRoomClicked; BtnToolbarDelete.Click += OnBtnToolbarDeleteClicked; } private void CenterOnSelectedTile() { CenterOnTile(State.Instance.SelectedTile.X, State.Instance.SelectedTile.Y); } private void CenterOnTile(int x, int y) { var center = new Point((Window.ClientBounds.Width + 200) / 2 - State.Instance.TileSize / 2, Window.ClientBounds.Height / 2 - State.Instance.TileSize / 2); var dx = center.X - x * State.Instance.TileSize - State.Instance.ViewportCenter.X; var dy = center.Y - y * State.Instance.TileSize - State.Instance.ViewportCenter.Y; State.Instance.ViewportCenter = new Vector3(State.Instance.ViewportCenter.X + dx, State.Instance.ViewportCenter.Y + dy, State.Instance.ViewportCenter.Z); } public void ClearSelection() { ClearSelection(GridWalls); ClearSelection(GridOverlays); ClearSelection(Toolbar); } private void ClearSelection(Grid grid) { foreach (var widget in grid.Widgets) widget.Border = null; } private void ClearSelection(HorizontalStackPanel grid) { foreach (var widget in grid.Widgets) widget.Border = null; } //TODO Refactor private void EditNote(Note note) { State.Instance.SelectedNote = new Note { X = note.X, Y = note.Y, Text = note.Text }; new NoteWindow(CommunicationManager, note).ShowInModalWindow(Desktop, $" Note on {note.X}:{note.Y}"); } private void OnBtnToolbarDeleteClicked(object sender, EventArgs e) { State.Instance.InsertMode = InsertMode.NewDelete; ClearSelection(); ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); ((ImageTextButton)sender).BorderThickness = new Thickness(2); } private void OnBtnToolbarLinClicked(object sender, EventArgs e) { State.Instance.InsertMode = InsertMode.NewLine; ClearSelection(); ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); ((ImageTextButton)sender).BorderThickness = new Thickness(2); } //private async void OnButtonJoinSessionClicked(object sender, EventArgs e) //{ // var localContent = ((TextButton)sender).GetParentContentInWindow(); // var isValid = localContent.Content.TxtSession.ValidateTextbox(); // if (!isValid) // { // return; // } // if (CommunicationManager.Connection.State != HubConnectionState.Connected) // { // lblConnectionStatus.Text = "Connecting"; // await CommunicationManager.Connection.StartAsync(); // UpdateConnectionState(CommunicationManager.Connection); // } // var successful = false; // try // { // var result = await CommunicationManager.Connection?.InvokeAsync("JoinSession", localContent.Content.TxtSession.Text); // if (result != null) // { // CommunicationManager.SessionData.Map = result.Map; // CommunicationManager.SessionData.Walls = result.Walls; // CommunicationManager.SessionData.Overlays = result.Overlays; // CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded; // CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted; // CommunicationManager.SessionData.MapEntityAdded += OnMapEntityAdded; // CommunicationManager.SessionData.MapEntityDeleted += OnMapEntityDeleted; // //CommunicationManager.SessionData.SessionId = result.SessionId; // //CommunicationManager.SessionData.SessionName = result.SessionName; // } // successful = result != null; // } // catch (Exception ex) // { // Console.WriteLine(ex.Message); // } // if (successful) // { // CommunicationManager.SessionData.SessionName = localContent.Content.TxtSession.Text; // lblMap.Text = CommunicationManager.SessionData.SessionName; // MenuConnectSync.Enabled = true; // MenuConnectUpload.Enabled = true; // localContent.Window.Close(); // } //} private void OnBtnToolbarRoomClicked(object sender, EventArgs e) { State.Instance.InsertMode = InsertMode.NewRoom; ClearSelection(); ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); ((ImageTextButton)sender).BorderThickness = new Thickness(2); } private void OnCampaignSelectedMessage(CampaignSelectedMessage obj) { lblCampaign.Text = State.Instance.CampaignName; MenuMapNew.Enabled = true; MenuMapOpen.Enabled = true; MenuCampaignPlayers.Enabled = true; } private void OnCenterOnTileMessage(CenterOnTileMessage obj) { CenterOnTile(obj.X, obj.Y); } private void OnErrorMessage(ErrorMessage obj) { new ErrorWindow(obj.Message).Toast(Desktop); } private void OneMenuFileSettingsSelected(object sender, EventArgs e) { var propertyGrid = new PropertyGrid { Object = Settings.Instance, Width = 350 }; var _windowEditor = new Window { Title = "Object Editor", Content = propertyGrid }; _windowEditor.ShowModal(Desktop); } private void OnLoginSuccesfulMessage(LoginSuccesfulMessage obj) { //MenuConnectNew.Enabled = true; //MenuConnectJoin.Enabled = true; MenuCampaignOpen.Enabled = true; MenuCampaingNew.Enabled = true; MenuMapNew.Enabled = false; MenuMapOpen.Enabled = false; MenuConnectSync.Enabled = false; MenuConnectUpload.Enabled = false; MenuCampaignPlayers.Enabled = false; lblCampaign.Text = "n/a"; lblMap.Text = "n/a"; //await CommunicationManager.ResetSignalrConnection(); CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded; CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted; lblUsername.Text = $"{obj.Initials}"; } private void OnMapEntityAdded(object sender, MapEntityAddedEventArgs e) { CommunicationManager.Enqueue(e.MapEntity, TileAction.Add); } private void OnMapEntityDeleted(object sender, MapEntityDeletedEventArgs e) { CommunicationManager.Enqueue(e.MapEntity, TileAction.Delete); } private async void OnMapOpenedMessage(MapOpenedMessage obj) { lblMap.Text = obj.MapName; State.Instance.MapId = obj.MapId; State.Instance.MapName = obj.MapName; CommunicationManager.SessionData.SessionName = obj.MapName; CommunicationManager.SessionData.SessionId = obj.MapId; MenuConnectSync.Enabled = true; MenuConnectUpload.Enabled = true; CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded; CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted; CommunicationManager.SessionData.MapEntityAdded += OnMapEntityAdded; CommunicationManager.SessionData.MapEntityDeleted += OnMapEntityDeleted; var serverMap = await CommunicationManager.Api.GetMap(State.Instance.CampaignId, State.Instance.MapId); if (CommunicationManager.Connection.State != HubConnectionState.Connected) { try { } catch (Exception e) { Console.WriteLine(e); throw; } await CommunicationManager.Connection.StartAsync(); UpdateConnectionState(CommunicationManager.Connection); } var result = await CommunicationManager.Connection?.InvokeAsync("JoinSession", State.Instance.MapId); CommunicationManager.SessionData.Overlays = serverMap.Overlays; CommunicationManager.SessionData.Map = serverMap.Map; CommunicationManager.SessionData.Walls = serverMap.Walls; CommunicationManager.SessionData.Notes = serverMap.Notes; CommunicationManager.SessionData.Lines = serverMap.Lines; CommunicationManager.SessionData.Rooms = serverMap.Rooms; } private void OnMenuCampaignNew(object sender, EventArgs e) { if (sender is MenuItem { Enabled: false }) return; new CampaignWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "New campaign"); ; } private async void OnMenuCampaignOpen(object sender, EventArgs e) { if (!((MenuItem)sender).Enabled) return; var content = new CampaignList(CommunicationManager, Messenger); if (await content.LoadCampaigns()) { content.ShowInModalWindow(Desktop, "Campaigns"); } } private async void OnMenuCampaignPlayersSelected(object sender, EventArgs e) { if (!((MenuItem)sender).Enabled) return; var content = new PlayerList(CommunicationManager, Messenger); if (await content.LoadPlayers()) { content.ShowInModalWindow(Desktop, "Players"); } } private void OnMenuConnectLoginSelected(object sender, EventArgs e) { Window window = new() { Title = "Login" }; var content = new LoginRegisterWindow(CommunicationManager, Messenger); window.Content = content; window.ShowModal(Desktop); } private async void OnMenuConnectSyncSelected(object sender, EventArgs e) { if (!((MenuItem)sender).Enabled) return; var serverMap = await CommunicationManager.Api.GetMap(State.Instance.CampaignId, State.Instance.MapId); CommunicationManager.SessionData.Overlays = serverMap.Overlays; CommunicationManager.SessionData.Map = serverMap.Map; CommunicationManager.SessionData.Walls = serverMap.Walls; CommunicationManager.SessionData.Notes = serverMap.Notes; CommunicationManager.SessionData.Lines = serverMap.Lines; CommunicationManager.SessionData.Rooms = serverMap.Rooms; } private async void OnMenuConnectUploadSelected(object sender, EventArgs e) { if (!((MenuItem)sender).Enabled) return; await CommunicationManager.Api.SaveSnapshot(CommunicationManager.SessionData, State.Instance.MapId); } private void OnMenuFileLoadSelected(object sender, EventArgs e) { var dialog = new FileDialog(FileDialogMode.OpenFile) { Filter = "*.map" }; dialog.Closed += (s, a) => { if (!dialog.Result) return; using var file = File.OpenText(dialog.FilePath); JsonSerializer serializer = new(); var loadData = (Session)serializer.Deserialize(file, typeof(Session)); CommunicationManager.SessionData.Map = loadData.Map; CommunicationManager.SessionData.Overlays = loadData.Overlays; CommunicationManager.SessionData.Walls = loadData.Walls; CommunicationManager.SessionData.Rooms = loadData.Rooms; CommunicationManager.SessionData.Lines = loadData.Lines; }; dialog.ShowModal(Desktop); } private void OnMenuFileSaveSelected(object sender, EventArgs e) { FileDialog dialog = new(FileDialogMode.SaveFile) { Filter = "*.map" }; dialog.Closed += (s, a) => { if (!dialog.Result) return; using var file = File.CreateText(dialog.FilePath); JsonSerializer serializer = new(); serializer.Serialize(file, CommunicationManager.SessionData); }; dialog.ShowModal(Desktop); } private void OnMenuMapNew(object sender, EventArgs e) { if (sender is MenuItem { Enabled: false }) return; new MapWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "New map"); } private async void OnMenuMapOpen(object sender, EventArgs e) { if (!((MenuItem)sender).Enabled) return; var content = new MapList(CommunicationManager, Messenger); if (await content.LoadMaps()) { content.ShowInModalWindow(Desktop, "Maps"); } } private void OnMenuViewCenterOnSelectionSelected(object sender, EventArgs e) { CenterOnSelectedTile(); } private void OnMenuViewNotesSelected(object sender, EventArgs e) { new NoteList(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "Notes"); } private void OnMenuViewShowCellNUmbersSelected(object sender, EventArgs e) { State.Instance.ShowCellNumbers = !State.Instance.ShowCellNumbers; } private async void OnSignalrConnectionUpdateMessage(SignalrConnectionUpdateMessage obj) { lblConnectionStatus.Text = "Connecting"; await CommunicationManager.Connection.StartAsync(); UpdateConnectionState(CommunicationManager.Connection); } private void UpdateConnectionState(HubConnection connection) { switch (connection.State) { case HubConnectionState.Connected: lblConnectionStatus.Text = "Connected"; break; case HubConnectionState.Connecting: lblConnectionStatus.Text = "Connecting"; break; case HubConnectionState.Disconnected: lblConnectionStatus.Text = "Disconnected"; break; case HubConnectionState.Reconnecting: lblConnectionStatus.Text = "Reconnecting"; break; } } } }