diff --git a/dvmconsole/App.xaml.cs b/dvmconsole/App.xaml.cs index 1de69e8..abb4dc9 100644 --- a/dvmconsole/App.xaml.cs +++ b/dvmconsole/App.xaml.cs @@ -15,9 +15,6 @@ using System.IO; using System.Reflection; using System.Windows; -using MessageBox = System.Windows.Forms.MessageBox; -using MessageBoxButtons = System.Windows.Forms.MessageBoxButtons; -using MessageBoxIcon = System.Windows.Forms.MessageBoxIcon; namespace dvmconsole { @@ -42,7 +39,7 @@ namespace dvmconsole if (!File.Exists(Path.Combine(new string[] { Path.GetDirectoryName(path), "libvocoder.DLL" }))) { MessageBox.Show("libvocoder is missing or not found! The library is required for operation of the console, please see: https://github.com/DVMProject/dvmvocoder.", "Digital Voice Modem - Desktop Dispatch Console", - MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBoxButton.OK, MessageBoxImage.Error); Application.Current.Shutdown(); return; } diff --git a/dvmconsole/Assets/bg_main_hd.png b/dvmconsole/Assets/bg_main_hd.png new file mode 100644 index 0000000..12168df Binary files /dev/null and b/dvmconsole/Assets/bg_main_hd.png differ diff --git a/dvmconsole/DVMConsole.csproj b/dvmconsole/DVMConsole.csproj index 54a77fd..8da7544 100644 --- a/dvmconsole/DVMConsole.csproj +++ b/dvmconsole/DVMConsole.csproj @@ -21,6 +21,7 @@ + @@ -58,6 +59,9 @@ Always + + Always + diff --git a/dvmconsole/KeyStatusWindow.xaml.cs b/dvmconsole/KeyStatusWindow.xaml.cs index 46102c1..8dc46f2 100644 --- a/dvmconsole/KeyStatusWindow.xaml.cs +++ b/dvmconsole/KeyStatusWindow.xaml.cs @@ -91,7 +91,7 @@ namespace dvmconsole { KeyStatusItems.Clear(); - foreach (var child in mainWindow.ChannelsCanvas.Children) + foreach (var child in mainWindow.channelsCanvas.Children) { if (child == null) { diff --git a/dvmconsole/MainWindow.xaml b/dvmconsole/MainWindow.xaml index 0dea668..d0b9701 100644 --- a/dvmconsole/MainWindow.xaml +++ b/dvmconsole/MainWindow.xaml @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:dvmconsole.Controls" - Title="Digital Voice Modem - Desktop Dispatch Console" Height="600" Width="875" MinHeight="600" MinWidth="875" Background="#FFF2F2F2" Icon="/Assets/AppIcon.ico"> + Title="Digital Voice Modem - Desktop Dispatch Console" Height="600" Width="875" Background="#FFF2F2F2" Icon="/Assets/AppIcon.ico"> @@ -34,6 +34,7 @@ + @@ -52,8 +53,12 @@ - - + + + + + + diff --git a/dvmconsole/MainWindow.xaml.cs b/dvmconsole/MainWindow.xaml.cs index 39d8b42..fc48688 100644 --- a/dvmconsole/MainWindow.xaml.cs +++ b/dvmconsole/MainWindow.xaml.cs @@ -36,6 +36,7 @@ using fnecore; using fnecore.P25; using fnecore.P25.LC.TSBK; using fnecore.P25.KMM; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window; namespace dvmconsole { @@ -63,6 +64,9 @@ namespace dvmconsole /// public partial class MainWindow : Window { + public const double MIN_WIDTH = 875; + public const double MIN_HEIGHT = 700; + private bool isEditMode = false; private bool globalPttState = false; @@ -75,6 +79,7 @@ namespace dvmconsole private double offsetY; private bool isDragging; + private bool windowLoaded = false; private bool noSaveSettingsOnClose = false; private SettingsManager settingsManager = new SettingsManager(); private SelectedChannelsManager selectedChannelsManager; @@ -119,12 +124,15 @@ namespace dvmconsole { InitializeComponent(); + MinWidth = Width = MIN_WIDTH; + MinHeight = Height = MIN_HEIGHT; + DisableControls(); settingsManager.LoadSettings(); selectedChannelsManager = new SelectedChannelsManager(); - flashingManager = new FlashingBackgroundManager(null, ChannelsCanvas, null, this); + flashingManager = new FlashingBackgroundManager(null, channelsCanvas, null, this); emergencyAlertPlayback = new WaveFilePlaybackManager(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Audio/emergency.wav")); channelHoldTimer = new System.Timers.Timer(10000); @@ -141,6 +149,7 @@ namespace dvmconsole audioManager = new AudioManager(settingsManager); selectedChannelsManager.SelectedChannelsChanged += SelectedChannelsChanged; + SizeChanged += MainWindow_SizeChanged; Loaded += MainWindow_Loaded; } @@ -149,8 +158,6 @@ namespace dvmconsole /// private void EnableControls() { - menuEditMode.IsEnabled = true; - menuPageSubscriber.IsEnabled = true; menuRadioCheckSubscriber.IsEnabled = true; menuInhibitSubscriber.IsEnabled = true; @@ -172,8 +179,6 @@ namespace dvmconsole /// private void DisableControls() { - menuEditMode.IsEnabled = false; - menuPageSubscriber.IsEnabled = false; menuRadioCheckSubscriber.IsEnabled = false; menuInhibitSubscriber.IsEnabled = false; @@ -260,7 +265,7 @@ namespace dvmconsole /// private void GenerateChannelWidgets() { - ChannelsCanvas.Children.Clear(); + channelsCanvas.Children.Clear(); double offsetX = 20; double offsetY = 20; @@ -285,10 +290,10 @@ namespace dvmconsole systemStatusBox.MouseLeftButtonUp += SystemStatusBox_MouseLeftButtonUp; systemStatusBox.MouseMove += SystemStatusBox_MouseMove; - ChannelsCanvas.Children.Add(systemStatusBox); + channelsCanvas.Children.Add(systemStatusBox); offsetX += 225; - if (offsetX + 220 > ChannelsCanvas.ActualWidth) + if (offsetX + 220 > channelsCanvas.ActualWidth) { offsetX = 20; offsetY += 106; @@ -361,11 +366,11 @@ namespace dvmconsole channelBox.MouseLeftButtonDown += ChannelBox_MouseLeftButtonDown; channelBox.MouseLeftButtonUp += ChannelBox_MouseLeftButtonUp; channelBox.MouseMove += ChannelBox_MouseMove; - ChannelsCanvas.Children.Add(channelBox); + channelsCanvas.Children.Add(channelBox); offsetX += 225; - if (offsetX + 220 > ChannelsCanvas.ActualWidth) + if (offsetX + 220 > channelsCanvas.ActualWidth) { offsetX = 20; offsetY += 106; @@ -394,7 +399,7 @@ namespace dvmconsole alertTone.MouseRightButtonUp += AlertTone_MouseRightButtonUp; - ChannelsCanvas.Children.Add(alertTone); + channelsCanvas.Children.Add(alertTone); } } @@ -418,17 +423,7 @@ namespace dvmconsole playbackChannelBox.MouseLeftButtonDown += ChannelBox_MouseLeftButtonDown; playbackChannelBox.MouseLeftButtonUp += ChannelBox_MouseLeftButtonUp; playbackChannelBox.MouseMove += ChannelBox_MouseMove; - ChannelsCanvas.Children.Add(playbackChannelBox); - - //offsetX += 225; - - //if (offsetX + 220 > ChannelsCanvas.ActualWidth) - //{ - // offsetX = 20; - // offsetY += 106; - //} - - AdjustCanvasHeight(); + channelsCanvas.Children.Add(playbackChannelBox); } /// @@ -964,7 +959,7 @@ namespace dvmconsole if (!isEditMode || !(sender is UIElement element)) return; draggedElement = element; - startPoint = e.GetPosition(ChannelsCanvas); + startPoint = e.GetPosition(channelsCanvas); offsetX = startPoint.X - Canvas.GetLeft(draggedElement); offsetY = startPoint.Y - Canvas.GetTop(draggedElement); isDragging = true; @@ -997,15 +992,15 @@ namespace dvmconsole if (!isEditMode || !isDragging || draggedElement == null) return; - Point currentPosition = e.GetPosition(ChannelsCanvas); + Point currentPosition = e.GetPosition(channelsCanvas); // Calculate the new position with snapping to the grid double newLeft = Math.Round((currentPosition.X - offsetX) / GridSize) * GridSize; double newTop = Math.Round((currentPosition.Y - offsetY) / GridSize) * GridSize; // Ensure the box stays within canvas bounds - newLeft = Math.Max(0, Math.Min(newLeft, ChannelsCanvas.ActualWidth - draggedElement.RenderSize.Width)); - newTop = Math.Max(0, Math.Min(newTop, ChannelsCanvas.ActualHeight - draggedElement.RenderSize.Height)); + newLeft = Math.Max(0, Math.Min(newLeft, channelsCanvas.ActualWidth - draggedElement.RenderSize.Width)); + newTop = Math.Max(0, Math.Min(newTop, channelsCanvas.ActualHeight - draggedElement.RenderSize.Height)); // Apply snapped position Canvas.SetLeft(draggedElement, newLeft); @@ -1014,8 +1009,6 @@ namespace dvmconsole // Save the new position if it's a ChannelBox if (draggedElement is ChannelBox channelBox) settingsManager.UpdateChannelPosition(channelBox.ChannelName, newLeft, newTop); - - AdjustCanvasHeight(); } /// @@ -1042,8 +1035,6 @@ namespace dvmconsole settingsManager.SystemStatusPositions[systemStatusBox.SystemName] = new ChannelPosition { X = x, Y = y }; ChannelBox_MouseLeftButtonUp(sender, e); - - AdjustCanvasHeight(); } } @@ -1072,7 +1063,7 @@ namespace dvmconsole /// private void UpdateEditModeForWidgets() { - foreach (var child in ChannelsCanvas.Children) + foreach (var child in channelsCanvas.Children) { if (child is AlertTone alertTone) alertTone.IsEditMode = isEditMode; @@ -1082,6 +1073,38 @@ namespace dvmconsole } } + /// + /// + /// + /// + /// + private void ResizeCanvasToWindow_Click(object sender, RoutedEventArgs e) + { + const double widthOffset = 16; + const double heightOffset = 115; + + foreach (UIElement child in channelsCanvas.Children) + { + double childLeft = Canvas.GetLeft(child) + child.RenderSize.Width; + if (childLeft > ActualWidth) + Canvas.SetLeft(child, ActualWidth - (child.RenderSize.Width + widthOffset)); + double childBottom = Canvas.GetTop(child) + child.RenderSize.Height; + if (childBottom > ActualHeight) + Canvas.SetTop(child, ActualHeight - (child.RenderSize.Height + heightOffset)); + } + + channelsCanvas.Width = ActualWidth; + canvasScrollViewer.Width = ActualWidth; + channelsCanvas.Height = ActualHeight; + canvasScrollViewer.Height = ActualHeight; + + settingsManager.CanvasWidth = ActualWidth; + settingsManager.CanvasHeight = ActualHeight; + + settingsManager.WindowWidth = ActualWidth; + settingsManager.WindowHeight = ActualHeight; + } + /// /// /// @@ -1115,10 +1138,8 @@ namespace dvmconsole alertTone.MouseRightButtonUp += AlertTone_MouseRightButtonUp; - ChannelsCanvas.Children.Add(alertTone); + channelsCanvas.Children.Add(alertTone); settingsManager.UpdateAlertTonePaths(alertFilePath); - - AdjustCanvasHeight(); } } @@ -1136,26 +1157,49 @@ namespace dvmconsole double x = Canvas.GetLeft(alertTone); double y = Canvas.GetTop(alertTone); settingsManager.UpdateAlertTonePosition(alertTone.AlertFilePath, x, y); - - AdjustCanvasHeight(); } } /// /// /// - private void AdjustCanvasHeight() + /// + /// + /// + private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e) { - double maxBottom = 0; + const double widthOffset = 16; + const double heightOffset = 115; - foreach (UIElement child in ChannelsCanvas.Children) + if (!windowLoaded) + return; + + if (ActualWidth > channelsCanvas.ActualWidth) { - double childBottom = Canvas.GetTop(child) + child.RenderSize.Height; - if (childBottom > maxBottom) - maxBottom = childBottom; + channelsCanvas.Width = ActualWidth; + canvasScrollViewer.Width = ActualWidth; } + else + canvasScrollViewer.Width = Width - widthOffset; + + if (ActualHeight > channelsCanvas.ActualHeight) + { + channelsCanvas.Height = ActualHeight; + canvasScrollViewer.Height = ActualHeight; + } + else + canvasScrollViewer.Height = Height - heightOffset; - ChannelsCanvas.Height = maxBottom + 150; + if (WindowState == WindowState.Maximized) + ResizeCanvasToWindow_Click(sender, e); + else + settingsManager.Maximized = false; + + settingsManager.CanvasWidth = channelsCanvas.ActualWidth; + settingsManager.CanvasHeight = channelsCanvas.ActualHeight; + + settingsManager.WindowWidth = ActualWidth; + settingsManager.WindowHeight = ActualHeight; } /// @@ -1165,10 +1209,32 @@ namespace dvmconsole /// private void MainWindow_Loaded(object sender, RoutedEventArgs e) { + const double widthOffset = 16; + const double heightOffset = 115; + if (!string.IsNullOrEmpty(settingsManager.LastCodeplugPath) && File.Exists(settingsManager.LastCodeplugPath)) LoadCodeplug(settingsManager.LastCodeplugPath); else GenerateChannelWidgets(); + + if (settingsManager.Maximized) + { + windowLoaded = true; + WindowState = WindowState.Maximized; + //Application.Current.MainWindow.WindowState = WindowState.Maximized; + ResizeCanvasToWindow_Click(sender, e); + } + else + { + Width = settingsManager.WindowWidth; + channelsCanvas.Width = settingsManager.CanvasWidth; + canvasScrollViewer.Width = ActualWidth - widthOffset; + Height = settingsManager.WindowHeight; + channelsCanvas.Height = settingsManager.CanvasHeight; + canvasScrollViewer.Height = ActualHeight - heightOffset; + + windowLoaded = true; + } } /// @@ -1204,7 +1270,12 @@ namespace dvmconsole protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { if (!noSaveSettingsOnClose) + { + if (WindowState == WindowState.Maximized) + settingsManager.Maximized = true; + settingsManager.SaveSettings(); + } base.OnClosing(e); Application.Current.Shutdown(); @@ -1316,7 +1387,7 @@ namespace dvmconsole private void SelectAll_Click(object sender, RoutedEventArgs e) { selectAll = !selectAll; - foreach (ChannelBox channel in ChannelsCanvas.Children.OfType()) + foreach (ChannelBox channel in channelsCanvas.Children.OfType()) { if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG) continue; diff --git a/dvmconsole/SettingsManager.cs b/dvmconsole/SettingsManager.cs index 3cf1fce..fe79d60 100644 --- a/dvmconsole/SettingsManager.cs +++ b/dvmconsole/SettingsManager.cs @@ -75,6 +75,27 @@ namespace dvmconsole /// public Dictionary ChannelOutputDevices { get; set; } = new Dictionary(); + /// + /// + /// + public bool Maximized { get; set; } = false; + /// + /// + /// + public double WindowWidth { get; set; } = MainWindow.MIN_WIDTH; + /// + /// + /// + public double WindowHeight { get; set; } = MainWindow.MIN_HEIGHT; + /// + /// + /// + public double CanvasWidth { get; set; } = MainWindow.MIN_WIDTH; + /// + /// + /// + public double CanvasHeight { get; set; } = MainWindow.MIN_HEIGHT; + /* ** Methods */ @@ -106,6 +127,24 @@ namespace dvmconsole AlertToneFilePaths = loadedSettings.AlertToneFilePaths ?? new List(); AlertTonePositions = loadedSettings.AlertTonePositions ?? new Dictionary(); ChannelOutputDevices = loadedSettings.ChannelOutputDevices ?? new Dictionary(); + Maximized = loadedSettings.Maximized; + WindowWidth = loadedSettings.WindowWidth; + if (WindowWidth == 0) + WindowWidth = MainWindow.MIN_WIDTH; + WindowHeight = loadedSettings.WindowHeight; + if (WindowHeight == 0) + WindowHeight = MainWindow.MIN_HEIGHT; + CanvasWidth = loadedSettings.CanvasWidth; + if (CanvasWidth == 0) + CanvasWidth = MainWindow.MIN_WIDTH; + CanvasHeight = loadedSettings.CanvasHeight; + if (CanvasHeight == 0) + CanvasHeight = MainWindow.MIN_HEIGHT; + + if (CanvasWidth < WindowWidth) + CanvasWidth = WindowWidth; + if (CanvasHeight < WindowHeight) + CanvasHeight = WindowHeight; return true; }