Added WLC-ALERT Buttons

pull/1/head
WhatTheReL 1 year ago committed by GitHub
parent 3f84281574
commit 24f784c7b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,9 +1,9 @@
<Application x:Class="WhackerLinkConsoleV2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WhackerLinkConsoleV2"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
<Application x:Class="WhackerLinkConsoleV2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WhackerLinkConsoleV2"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

@ -1,14 +1,14 @@
using System.Configuration;
using System.Data;
using System.Windows;
namespace WhackerLinkConsoleV2
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
using System.Configuration;
using System.Data;
using System.Windows;
namespace WhackerLinkConsoleV2
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

@ -1,10 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

@ -1,22 +1,22 @@
<UserControl x:Class="WhackerLinkConsoleV2.Controls.ChannelBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="120" Background="#222222" BorderBrush="Gray" BorderThickness="2">
<Border CornerRadius="5" Background="{Binding Background, RelativeSource={RelativeSource AncestorType=UserControl}}">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding ChannelName}" FontWeight="Bold" Foreground="White" FontSize="14" Grid.Row="0"/>
<TextBlock Text="{Binding SystemName}" Foreground="LightGray" FontSize="12" Grid.Row="1"/>
<TextBlock Text="{Binding TGID}" Foreground="LightGray" FontSize="12" Grid.Row="2"/>
<Button Content="PTT" Width="80" Margin="0,5,0,0" Background="Green" Foreground="White"
HorizontalAlignment="Left" Grid.Row="3" Click="PTTButton_Click"/>
</Grid>
</Border>
</UserControl>
<UserControl x:Class="WhackerLinkConsoleV2.Controls.ChannelBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="120" Background="#222222" BorderBrush="Gray" BorderThickness="2">
<Border CornerRadius="5" Background="{Binding Background, RelativeSource={RelativeSource AncestorType=UserControl}}">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding ChannelName}" FontWeight="Bold" Foreground="White" FontSize="14" Grid.Row="0"/>
<TextBlock Text="{Binding SystemName}" Foreground="LightGray" FontSize="12" Grid.Row="1"/>
<TextBlock Text="{Binding TGID}" Foreground="LightGray" FontSize="12" Grid.Row="2"/>
<Button Content="PTT" Width="80" Margin="0,5,0,0" Background="Green" Foreground="White"
HorizontalAlignment="Left" Grid.Row="3" Click="PTTButton_Click"/>
</Grid>
</Border>
</UserControl>

@ -1,85 +1,85 @@
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WhackerLinkConsoleV2.Controls
{
public partial class ChannelBox : UserControl
{
public string ChannelName { get; set; }
public string SystemName { get; set; }
public string TGID { get; set; }
public ChannelBox()
{
InitializeComponent();
DataContext = this;
MouseMove += ChannelBox_MouseMove;
MouseDown += ChannelBox_MouseDown;
MouseUp += ChannelBox_MouseUp;
}
public ChannelBox(string channelName, string systemName, string tgid) : this()
{
ChannelName = $"{channelName}";
SystemName = $"System: {systemName}";
TGID = $"TGID: {tgid}";
}
private Point _dragStartPoint;
private bool _isDragging;
private void ChannelBox_MouseDown(object sender, MouseButtonEventArgs e)
{
_dragStartPoint = e.GetPosition(null);
_isDragging = false;
}
private void ChannelBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point currentPosition = e.GetPosition(null);
if (!_isDragging && (Math.Abs(currentPosition.X - _dragStartPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(currentPosition.Y - _dragStartPoint.Y) > SystemParameters.MinimumVerticalDragDistance))
{
_isDragging = true;
DataObject data = new DataObject("ChannelBox", this);
DragDrop.DoDragDrop(this, data, DragDropEffects.Move);
}
}
}
private void ChannelBox_MouseUp(object sender, MouseButtonEventArgs e)
{
_isDragging = false;
}
private void PTTButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show($"Imagine you were talking on {ChannelName} rn");
}
}
}
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WhackerLinkConsoleV2.Controls
{
public partial class ChannelBox : UserControl
{
public string ChannelName { get; set; }
public string SystemName { get; set; }
public string TGID { get; set; }
public ChannelBox()
{
InitializeComponent();
DataContext = this;
MouseMove += ChannelBox_MouseMove;
MouseDown += ChannelBox_MouseDown;
MouseUp += ChannelBox_MouseUp;
}
public ChannelBox(string channelName, string systemName, string tgid) : this()
{
ChannelName = $"{channelName}";
SystemName = $"System: {systemName}";
TGID = $"TGID: {tgid}";
}
private Point _dragStartPoint;
private bool _isDragging;
private void ChannelBox_MouseDown(object sender, MouseButtonEventArgs e)
{
_dragStartPoint = e.GetPosition(null);
_isDragging = false;
}
private void ChannelBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point currentPosition = e.GetPosition(null);
if (!_isDragging && (Math.Abs(currentPosition.X - _dragStartPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(currentPosition.Y - _dragStartPoint.Y) > SystemParameters.MinimumVerticalDragDistance))
{
_isDragging = true;
DataObject data = new DataObject("ChannelBox", this);
DragDrop.DoDragDrop(this, data, DragDropEffects.Move);
}
}
}
private void ChannelBox_MouseUp(object sender, MouseButtonEventArgs e)
{
_isDragging = false;
}
private void PTTButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show($"Imagine you were talking on {ChannelName} rn");
}
}
}

@ -1,28 +1,28 @@
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
namespace WhackerLinkConsoleV2
{
public class ChannelPosition
{
public double X { get; set; }
public double Y { get; set; }
}
}
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
namespace WhackerLinkConsoleV2
{
public class ChannelPosition
{
public double X { get; set; }
public double Y { get; set; }
}
}

@ -1,20 +1,53 @@
<Window x:Class="WhackerLinkConsoleV2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WhackerLinkConsoleV2.Controls"
Title="WhackerLinkConsoleV2" Height="600" Width="1000" Background="#1e1e1e">
<Grid>
<Menu VerticalAlignment="Top" Height="25">
<MenuItem Header="File">
<MenuItem Header="Open Codeplug" Click="OpenCodeplug_Click"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Enable Edit Mode" Click="ToggleEditMode_Click"/>
<MenuItem Header="Select Widgets to Display" Click="SelectWidgets_Click"/>
<MenuItem Header="Reset Settings" Click="ResetSettings_Click"/>
</MenuItem>
</Menu>
<Canvas x:Name="ChannelsCanvas" Margin="0,25,0,0" Background="#1e1e1e" />
</Grid>
</Window>
<Window x:Class="WhackerLinkConsoleV2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WhackerLinkConsoleV2.Controls"
Title="WhackerLinkConsoleV2" Height="600" Width="1000" Background="#1e1e1e">
<Grid>
<Menu VerticalAlignment="Top" Height="25">
<MenuItem Header="File">
<MenuItem Header="Open Codeplug" Click="OpenCodeplug_Click"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Enable Edit Mode" Click="ToggleEditMode_Click"/>
<MenuItem Header="Select Widgets to Display" Click="SelectWidgets_Click"/>
<MenuItem Header="Reset Settings" Click="ResetSettings_Click"/>
</MenuItem>
</Menu>
<Canvas x:Name="ChannelsCanvas" Margin="0,25,0,0" Background="#1e1e1e">
</Canvas>
<Grid VerticalAlignment="Top" Height="75" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center">
<Button Content="ALERT 1" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 2" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 3" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 4" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 5" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 6" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 7" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 8" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 9" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 10" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 11" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 12" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 13" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 14" Height="47" Width="53" Click="Button_Click" />
<Button Content="ALERT 15" Height="47" Width="53" Click="Button_Click" />
</StackPanel>
</Grid>
</Grid>
</Window>

@ -1,242 +1,250 @@
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using Microsoft.Win32;
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using WhackerLinkLib.Models.Radio;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using WhackerLinkConsoleV2.Controls;
using System.Collections.Generic;
namespace WhackerLinkConsoleV2
{
public partial class MainWindow : Window
{
public Codeplug Codeplug { get; set; }
private bool isEditMode = false;
private UIElement _draggedElement;
private Point _startPoint;
private double _offsetX;
private double _offsetY;
private bool _isDragging;
private SettingsManager _settingsManager = new SettingsManager();
public MainWindow()
{
InitializeComponent();
_settingsManager.LoadSettings();
Loaded += MainWindow_Loaded;
}
private void OpenCodeplug_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "Codeplug Files (*.yml)|*.yml|All Files (*.*)|*.*",
Title = "Open Codeplug"
};
if (openFileDialog.ShowDialog() == true)
{
LoadCodeplug(openFileDialog.FileName);
_settingsManager.LastCodeplugPath = openFileDialog.FileName;
_settingsManager.SaveSettings();
}
}
private void ResetSettings_Click(object sender, RoutedEventArgs e)
{
if (File.Exists("UserSettings.json"))
File.Delete("UserSettings.json");
}
private void LoadCodeplug(string filePath)
{
try
{
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
var yaml = File.ReadAllText(filePath);
Codeplug = deserializer.Deserialize<Codeplug>(yaml);
GenerateChannelWidgets();
}
catch (Exception ex)
{
MessageBox.Show($"Error loading codeplug: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void GenerateChannelWidgets()
{
ChannelsCanvas.Children.Clear();
double offsetX = 20;
double offsetY = 20;
if (_settingsManager.ShowSystemStatus && Codeplug != null)
{
foreach (var system in Codeplug.Systems)
{
var systemStatusBox = new SystemStatusBox(system.Name, system.Address, system.Port);
Canvas.SetLeft(systemStatusBox, offsetX);
Canvas.SetTop(systemStatusBox, offsetY);
systemStatusBox.MouseLeftButtonDown += SystemStatusBox_MouseLeftButtonDown;
systemStatusBox.MouseMove += SystemStatusBox_MouseMove;
systemStatusBox.MouseRightButtonDown += SystemStatusBox_MouseRightButtonDown;
ChannelsCanvas.Children.Add(systemStatusBox);
offsetX += 220;
if (offsetX + 200 > ChannelsCanvas.ActualWidth)
{
offsetX = 20;
offsetY += 140;
}
}
}
if (_settingsManager.ShowChannels && Codeplug != null)
{
foreach (var zone in Codeplug.Zones)
{
foreach (var channel in zone.Channels)
{
var channelBox = new ChannelBox(channel.Name, channel.System, channel.Tgid);
if (_settingsManager.ChannelPositions.TryGetValue(channel.Name, out var position))
{
Canvas.SetLeft(channelBox, position.X);
Canvas.SetTop(channelBox, position.Y);
}
else
{
Canvas.SetLeft(channelBox, offsetX);
Canvas.SetTop(channelBox, offsetY);
}
channelBox.MouseLeftButtonDown += ChannelBox_MouseLeftButtonDown;
channelBox.MouseMove += ChannelBox_MouseMove;
channelBox.MouseRightButtonDown += ChannelBox_MouseRightButtonDown;
ChannelsCanvas.Children.Add(channelBox);
offsetX += 220;
if (offsetX + 200 > ChannelsCanvas.ActualWidth)
{
offsetX = 20;
offsetY += 140;
}
}
}
}
}
private void SelectWidgets_Click(object sender, RoutedEventArgs e)
{
var widgetSelectionWindow = new WidgetSelectionWindow();
widgetSelectionWindow.Owner = this;
if (widgetSelectionWindow.ShowDialog() == true)
{
_settingsManager.ShowSystemStatus = widgetSelectionWindow.ShowSystemStatus;
_settingsManager.ShowChannels = widgetSelectionWindow.ShowChannels;
GenerateChannelWidgets();
_settingsManager.SaveSettings();
}
}
private void ChannelBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!isEditMode || !(sender is UIElement element)) return;
_draggedElement = element;
_startPoint = e.GetPosition(ChannelsCanvas);
_offsetX = _startPoint.X - Canvas.GetLeft(_draggedElement);
_offsetY = _startPoint.Y - Canvas.GetTop(_draggedElement);
_isDragging = true;
element.CaptureMouse();
}
private void ChannelBox_MouseMove(object sender, MouseEventArgs e)
{
if (!isEditMode || !_isDragging || _draggedElement == null) return;
Point currentPosition = e.GetPosition(ChannelsCanvas);
double newLeft = Math.Max(0, Math.Min(currentPosition.X - _offsetX, ChannelsCanvas.ActualWidth - _draggedElement.RenderSize.Width));
double newTop = Math.Max(0, Math.Min(currentPosition.Y - _offsetY, ChannelsCanvas.ActualHeight - _draggedElement.RenderSize.Height));
Canvas.SetLeft(_draggedElement, newLeft);
Canvas.SetTop(_draggedElement, newTop);
if (_draggedElement is ChannelBox channelBox)
{
_settingsManager.UpdateChannelPosition(channelBox.ChannelName, newLeft, newTop);
}
}
private void ChannelBox_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
if (!isEditMode || !_isDragging || _draggedElement == null) return;
_isDragging = false;
_draggedElement.ReleaseMouseCapture();
_draggedElement = null;
}
private void SystemStatusBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => ChannelBox_MouseLeftButtonDown(sender, e);
private void SystemStatusBox_MouseMove(object sender, MouseEventArgs e) => ChannelBox_MouseMove(sender, e);
private void SystemStatusBox_MouseRightButtonDown(object sender, MouseButtonEventArgs e) => ChannelBox_MouseRightButtonDown(sender, e);
private void ToggleEditMode_Click(object sender, RoutedEventArgs e)
{
isEditMode = !isEditMode;
var menuItem = (MenuItem)sender;
menuItem.Header = isEditMode ? "Disable Edit Mode" : "Enable Edit Mode";
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
_settingsManager.SaveSettings();
base.OnClosing(e);
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(_settingsManager.LastCodeplugPath) && File.Exists(_settingsManager.LastCodeplugPath))
{
LoadCodeplug(_settingsManager.LastCodeplugPath);
}
else
{
GenerateChannelWidgets();
}
}
}
}
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using Microsoft.Win32;
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using WhackerLinkLib.Models.Radio;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using WhackerLinkConsoleV2.Controls;
using System.Collections.Generic;
namespace WhackerLinkConsoleV2
{
public partial class MainWindow : Window
{
public Codeplug Codeplug { get; set; }
private bool isEditMode = false;
private UIElement _draggedElement;
private Point _startPoint;
private double _offsetX;
private double _offsetY;
private bool _isDragging;
private SettingsManager _settingsManager = new SettingsManager();
public MainWindow()
{
InitializeComponent();
_settingsManager.LoadSettings();
Loaded += MainWindow_Loaded;
}
private void OpenCodeplug_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "Codeplug Files (*.yml)|*.yml|All Files (*.*)|*.*",
Title = "Open Codeplug"
};
if (openFileDialog.ShowDialog() == true)
{
LoadCodeplug(openFileDialog.FileName);
_settingsManager.LastCodeplugPath = openFileDialog.FileName;
_settingsManager.SaveSettings();
}
}
private void ResetSettings_Click(object sender, RoutedEventArgs e)
{
if (File.Exists("UserSettings.json"))
File.Delete("UserSettings.json");
}
private void LoadCodeplug(string filePath)
{
try
{
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
var yaml = File.ReadAllText(filePath);
Codeplug = deserializer.Deserialize<Codeplug>(yaml);
GenerateChannelWidgets();
}
catch (Exception ex)
{
MessageBox.Show($"Error loading codeplug: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void GenerateChannelWidgets()
{
ChannelsCanvas.Children.Clear();
double offsetX = 20;
double offsetY = 20;
if (_settingsManager.ShowSystemStatus && Codeplug != null)
{
foreach (var system in Codeplug.Systems)
{
var systemStatusBox = new SystemStatusBox(system.Name, system.Address, system.Port);
Canvas.SetLeft(systemStatusBox, offsetX);
Canvas.SetTop(systemStatusBox, offsetY);
systemStatusBox.MouseLeftButtonDown += SystemStatusBox_MouseLeftButtonDown;
systemStatusBox.MouseMove += SystemStatusBox_MouseMove;
systemStatusBox.MouseRightButtonDown += SystemStatusBox_MouseRightButtonDown;
ChannelsCanvas.Children.Add(systemStatusBox);
offsetX += 220;
if (offsetX + 200 > ChannelsCanvas.ActualWidth)
{
offsetX = 20;
offsetY += 140;
}
}
}
if (_settingsManager.ShowChannels && Codeplug != null)
{
foreach (var zone in Codeplug.Zones)
{
foreach (var channel in zone.Channels)
{
var channelBox = new ChannelBox(channel.Name, channel.System, channel.Tgid);
if (_settingsManager.ChannelPositions.TryGetValue(channel.Name, out var position))
{
Canvas.SetLeft(channelBox, position.X);
Canvas.SetTop(channelBox, position.Y);
}
else
{
Canvas.SetLeft(channelBox, offsetX);
Canvas.SetTop(channelBox, offsetY);
}
channelBox.MouseLeftButtonDown += ChannelBox_MouseLeftButtonDown;
channelBox.MouseMove += ChannelBox_MouseMove;
channelBox.MouseRightButtonDown += ChannelBox_MouseRightButtonDown;
ChannelsCanvas.Children.Add(channelBox);
offsetX += 220;
if (offsetX + 200 > ChannelsCanvas.ActualWidth)
{
offsetX = 20;
offsetY += 140;
}
}
}
}
}
private void SelectWidgets_Click(object sender, RoutedEventArgs e)
{
var widgetSelectionWindow = new WidgetSelectionWindow();
widgetSelectionWindow.Owner = this;
if (widgetSelectionWindow.ShowDialog() == true)
{
_settingsManager.ShowSystemStatus = widgetSelectionWindow.ShowSystemStatus;
_settingsManager.ShowChannels = widgetSelectionWindow.ShowChannels;
GenerateChannelWidgets();
_settingsManager.SaveSettings();
}
}
private void ChannelBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!isEditMode || !(sender is UIElement element)) return;
_draggedElement = element;
_startPoint = e.GetPosition(ChannelsCanvas);
_offsetX = _startPoint.X - Canvas.GetLeft(_draggedElement);
_offsetY = _startPoint.Y - Canvas.GetTop(_draggedElement);
_isDragging = true;
element.CaptureMouse();
}
private void ChannelBox_MouseMove(object sender, MouseEventArgs e)
{
if (!isEditMode || !_isDragging || _draggedElement == null) return;
Point currentPosition = e.GetPosition(ChannelsCanvas);
double newLeft = Math.Max(0, Math.Min(currentPosition.X - _offsetX, ChannelsCanvas.ActualWidth - _draggedElement.RenderSize.Width));
double newTop = Math.Max(0, Math.Min(currentPosition.Y - _offsetY, ChannelsCanvas.ActualHeight - _draggedElement.RenderSize.Height));
Canvas.SetLeft(_draggedElement, newLeft);
Canvas.SetTop(_draggedElement, newTop);
if (_draggedElement is ChannelBox channelBox)
{
_settingsManager.UpdateChannelPosition(channelBox.ChannelName, newLeft, newTop);
}
}
private void ChannelBox_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
if (!isEditMode || !_isDragging || _draggedElement == null) return;
_isDragging = false;
_draggedElement.ReleaseMouseCapture();
_draggedElement = null;
}
private void SystemStatusBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => ChannelBox_MouseLeftButtonDown(sender, e);
private void SystemStatusBox_MouseMove(object sender, MouseEventArgs e) => ChannelBox_MouseMove(sender, e);
private void SystemStatusBox_MouseRightButtonDown(object sender, MouseButtonEventArgs e) => ChannelBox_MouseRightButtonDown(sender, e);
private void ToggleEditMode_Click(object sender, RoutedEventArgs e)
{
isEditMode = !isEditMode;
var menuItem = (MenuItem)sender;
menuItem.Header = isEditMode ? "Disable Edit Mode" : "Enable Edit Mode";
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
_settingsManager.SaveSettings();
base.OnClosing(e);
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(_settingsManager.LastCodeplugPath) && File.Exists(_settingsManager.LastCodeplugPath))
{
LoadCodeplug(_settingsManager.LastCodeplugPath);
}
else
{
GenerateChannelWidgets();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (sender is Button button)
{
string buttonContent = button.Content.ToString();
MessageBox.Show($"Beep boop {buttonContent}");
}
}
}
}

@ -1,85 +1,85 @@
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.IO;
using Newtonsoft.Json;
namespace WhackerLinkConsoleV2
{
public class SettingsManager
{
private const string SettingsFilePath = "UserSettings.json";
public bool ShowSystemStatus { get; set; } = true;
public bool ShowChannels { get; set; } = true;
public string LastCodeplugPath { get; set; } = null;
public Dictionary<string, ChannelPosition> ChannelPositions { get; set; } = new Dictionary<string, ChannelPosition>();
public void LoadSettings()
{
if (!File.Exists(SettingsFilePath)) return;
try
{
var json = File.ReadAllText(SettingsFilePath);
var loadedSettings = JsonConvert.DeserializeObject<SettingsManager>(json);
if (loadedSettings != null)
{
ShowSystemStatus = loadedSettings.ShowSystemStatus;
ShowChannels = loadedSettings.ShowChannels;
LastCodeplugPath = loadedSettings.LastCodeplugPath;
ChannelPositions = loadedSettings.ChannelPositions ?? new Dictionary<string, ChannelPosition>();
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading settings: {ex.Message}");
}
}
public void SaveSettings()
{
try
{
var json = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(SettingsFilePath, json);
}
catch (Exception ex)
{
Console.WriteLine($"Error saving settings: {ex.Message}");
}
}
public void UpdateChannelPosition(string channelName, double x, double y)
{
if (ChannelPositions.ContainsKey(channelName))
{
ChannelPositions[channelName].X = x;
ChannelPositions[channelName].Y = y;
}
else
{
ChannelPositions[channelName] = new ChannelPosition { X = x, Y = y };
}
}
}
}
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.IO;
using Newtonsoft.Json;
namespace WhackerLinkConsoleV2
{
public class SettingsManager
{
private const string SettingsFilePath = "UserSettings.json";
public bool ShowSystemStatus { get; set; } = true;
public bool ShowChannels { get; set; } = true;
public string LastCodeplugPath { get; set; } = null;
public Dictionary<string, ChannelPosition> ChannelPositions { get; set; } = new Dictionary<string, ChannelPosition>();
public void LoadSettings()
{
if (!File.Exists(SettingsFilePath)) return;
try
{
var json = File.ReadAllText(SettingsFilePath);
var loadedSettings = JsonConvert.DeserializeObject<SettingsManager>(json);
if (loadedSettings != null)
{
ShowSystemStatus = loadedSettings.ShowSystemStatus;
ShowChannels = loadedSettings.ShowChannels;
LastCodeplugPath = loadedSettings.LastCodeplugPath;
ChannelPositions = loadedSettings.ChannelPositions ?? new Dictionary<string, ChannelPosition>();
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading settings: {ex.Message}");
}
}
public void SaveSettings()
{
try
{
var json = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(SettingsFilePath, json);
}
catch (Exception ex)
{
Console.WriteLine($"Error saving settings: {ex.Message}");
}
}
public void UpdateChannelPosition(string channelName, double x, double y)
{
if (ChannelPositions.ContainsKey(channelName))
{
ChannelPositions[channelName].X = x;
ChannelPositions[channelName].Y = y;
}
else
{
ChannelPositions[channelName] = new ChannelPosition { X = x, Y = y };
}
}
}
}

@ -1,13 +1,13 @@
<UserControl x:Class="WhackerLinkConsoleV2.Controls.SystemStatusBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="120" Background="#334455" BorderBrush="Gray" BorderThickness="2">
<Border Background="{Binding Background, RelativeSource={RelativeSource AncestorType=UserControl}}" CornerRadius="5" Padding="10">
<StackPanel>
<TextBlock Text="{Binding SystemName}" FontWeight="Bold" Foreground="White" FontSize="14"/>
<TextBlock Text="{Binding AddressPort}" Foreground="LightGray" FontSize="12"/>
<TextBlock Text="Connection State:" Foreground="LightGray" FontSize="12"/>
<TextBlock Text="{Binding ConnectionState}" Foreground="White" FontSize="12"/>
</StackPanel>
</Border>
</UserControl>
<UserControl x:Class="WhackerLinkConsoleV2.Controls.SystemStatusBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="120" Background="#334455" BorderBrush="Gray" BorderThickness="2">
<Border Background="{Binding Background, RelativeSource={RelativeSource AncestorType=UserControl}}" CornerRadius="5" Padding="10">
<StackPanel>
<TextBlock Text="{Binding SystemName}" FontWeight="Bold" Foreground="White" FontSize="14"/>
<TextBlock Text="{Binding AddressPort}" Foreground="LightGray" FontSize="12"/>
<TextBlock Text="Connection State:" Foreground="LightGray" FontSize="12"/>
<TextBlock Text="{Binding ConnectionState}" Foreground="White" FontSize="12"/>
</StackPanel>
</Border>
</UserControl>

@ -1,43 +1,43 @@
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.Windows.Controls;
namespace WhackerLinkConsoleV2.Controls
{
public partial class SystemStatusBox : UserControl
{
public string SystemName { get; set; }
public string AddressPort { get; set; }
public string ConnectionState { get; set; } = "Disconnected";
public SystemStatusBox()
{
InitializeComponent();
DataContext = this;
}
public SystemStatusBox(string systemName, string address, int port) : this()
{
SystemName = systemName;
AddressPort = $"Address: {address}:{port}";
}
}
}
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.Windows.Controls;
namespace WhackerLinkConsoleV2.Controls
{
public partial class SystemStatusBox : UserControl
{
public string SystemName { get; set; }
public string AddressPort { get; set; }
public string ConnectionState { get; set; } = "Disconnected";
public SystemStatusBox()
{
InitializeComponent();
DataContext = this;
}
public SystemStatusBox(string systemName, string address, int port) : this()
{
SystemName = systemName;
AddressPort = $"Address: {address}:{port}";
}
}
}

@ -1,19 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="16.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WhackerLinkLib\WhackerLinkLib.csproj" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<None Remove="whackerlink-logo %281%29.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="16.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WhackerLinkLib\WhackerLinkLib.csproj" />
</ItemGroup>
<ItemGroup>
<Resource Include="whackerlink-logo (1).png" />
</ItemGroup>
</Project>

@ -1,11 +1,11 @@
<Window x:Class="WhackerLinkConsoleV2.WidgetSelectionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Select Widgets" Height="200" Width="300" WindowStartupLocation="CenterOwner">
<StackPanel Margin="20">
<TextBlock Text="Select Widgets to Display:" FontWeight="Bold" Margin="0,0,0,10" />
<CheckBox x:Name="SystemStatusCheckBox" Content="System Status" IsChecked="True" />
<CheckBox x:Name="ChannelCheckBox" Content="Channel" IsChecked="True" />
<Button Content="Apply" Width="80" Margin="0,20,0,0" HorizontalAlignment="Center" Click="ApplyButton_Click" />
</StackPanel>
</Window>
<Window x:Class="WhackerLinkConsoleV2.WidgetSelectionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Select Widgets" Height="200" Width="300" WindowStartupLocation="CenterOwner">
<StackPanel Margin="20">
<TextBlock Text="Select Widgets to Display:" FontWeight="Bold" Margin="0,0,0,10" />
<CheckBox x:Name="SystemStatusCheckBox" Content="System Status" IsChecked="True" />
<CheckBox x:Name="ChannelCheckBox" Content="Channel" IsChecked="True" />
<Button Content="Apply" Width="80" Margin="0,20,0,0" HorizontalAlignment="Center" Click="ApplyButton_Click" />
</StackPanel>
</Window>

@ -1,43 +1,43 @@
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.Windows;
namespace WhackerLinkConsoleV2
{
public partial class WidgetSelectionWindow : Window
{
public bool ShowSystemStatus { get; private set; } = true;
public bool ShowChannels { get; private set; } = true;
public WidgetSelectionWindow()
{
InitializeComponent();
}
private void ApplyButton_Click(object sender, RoutedEventArgs e)
{
ShowSystemStatus = SystemStatusCheckBox.IsChecked ?? false;
ShowChannels = ChannelCheckBox.IsChecked ?? false;
DialogResult = true;
Close();
}
}
}
/*
* WhackerLink - WhackerLinkConsoleV2
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
*
*/
using System.Windows;
namespace WhackerLinkConsoleV2
{
public partial class WidgetSelectionWindow : Window
{
public bool ShowSystemStatus { get; private set; } = true;
public bool ShowChannels { get; private set; } = true;
public WidgetSelectionWindow()
{
InitializeComponent();
}
private void ApplyButton_Click(object sender, RoutedEventArgs e)
{
ShowSystemStatus = SystemStatusCheckBox.IsChecked ?? false;
ShowChannels = ChannelCheckBox.IsChecked ?? false;
DialogResult = true;
Close();
}
}
}

Loading…
Cancel
Save

Powered by TurnKey Linux.