406 lines
13 KiB
C#
406 lines
13 KiB
C#
namespace PainoBar_Helper
|
|
{
|
|
public partial class Main : Form
|
|
{
|
|
private readonly ProfileManager _profileManager;
|
|
private readonly PianobarManager _pianobarManager;
|
|
private OutputManager? _outputManager;
|
|
private System.Windows.Forms.Timer? _statusTimer;
|
|
private bool _statusToggle = false;
|
|
|
|
// Connection status enum
|
|
private enum ConnectionStatus
|
|
{
|
|
Disconnected, // Red
|
|
ConnectedIdle, // Green
|
|
ConnectedActive // Blue
|
|
}
|
|
|
|
private ConnectionStatus _currentStatus = ConnectionStatus.Disconnected;
|
|
|
|
public Main()
|
|
{
|
|
InitializeComponent();
|
|
|
|
_profileManager = new ProfileManager();
|
|
_pianobarManager = new PianobarManager();
|
|
|
|
InitializeMenus();
|
|
InitializeStatusBar();
|
|
InitializeEvents();
|
|
UpdateProfilesMenu();
|
|
UpdateConnectionStatus(ConnectionStatus.Disconnected);
|
|
}
|
|
|
|
#region Initialization
|
|
|
|
private void InitializeMenus()
|
|
{
|
|
// File menu is assumed to be created in the Designer
|
|
// This method sets up dynamic profile menu items
|
|
}
|
|
|
|
private void InitializeStatusBar()
|
|
{
|
|
// Status bar zones are assumed to be created in the Designer:
|
|
// - statusLabelLeft: Connection indicator
|
|
// - statusLabelCenter: Alternating status (Profile/Station)
|
|
// - statusLabelRight: Event feed
|
|
|
|
_statusTimer = new System.Windows.Forms.Timer();
|
|
_statusTimer.Interval = 10000; // 10 seconds
|
|
_statusTimer.Tick += StatusTimer_Tick;
|
|
_statusTimer.Start();
|
|
|
|
UpdateCenterStatus();
|
|
}
|
|
|
|
private void InitializeEvents()
|
|
{
|
|
// Pianobar events
|
|
_pianobarManager.Connected += PianobarManager_Connected;
|
|
_pianobarManager.Disconnected += PianobarManager_Disconnected;
|
|
_pianobarManager.SongChanged += PianobarManager_SongChanged;
|
|
_pianobarManager.StationChanged += PianobarManager_StationChanged;
|
|
_pianobarManager.EventOccurred += PianobarManager_EventOccurred;
|
|
|
|
// Profile events
|
|
_profileManager.ProfilesChanged += ProfileManager_ProfilesChanged;
|
|
_profileManager.ActiveProfileChanged += ProfileManager_ActiveProfileChanged;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Button Event Handlers
|
|
|
|
// This method should be wired to btnConnect.Click in the Designer
|
|
public void btnConnect_Click(object? sender, EventArgs e)
|
|
{
|
|
if (_pianobarManager.IsConnected)
|
|
{
|
|
MessageBox.Show("Already connected to Pianobar.", "Already Connected",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Get pianobar.exe path (you may want to add a setting for this)
|
|
string pianobarPath = "pianobar.exe"; // Default, assumes it's in PATH
|
|
string? configPath = _profileManager.GetActiveConfigPath();
|
|
|
|
_pianobarManager.Connect(pianobarPath, configPath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Failed to connect to Pianobar:\n{ex.Message}", "Connection Error",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
// This method should be wired to btnDisconnect.Click in the Designer
|
|
public void btnDisconnect_Click(object? sender, EventArgs e)
|
|
{
|
|
if (!_pianobarManager.IsConnected)
|
|
{
|
|
MessageBox.Show("Not connected to Pianobar.", "Not Connected",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
return;
|
|
}
|
|
|
|
_pianobarManager.Disconnect();
|
|
_outputManager?.Stop();
|
|
}
|
|
|
|
// This method should be wired to btnPlayPause.Click in the Designer
|
|
public void btnPlayPause_Click(object? sender, EventArgs e)
|
|
{
|
|
if (!_pianobarManager.IsConnected)
|
|
{
|
|
MessageBox.Show("Not connected to Pianobar.", "Not Connected",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
_pianobarManager.PlayPause();
|
|
UpdatePlayPauseButton();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Failed to toggle play/pause:\n{ex.Message}", "Command Error",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
// This method should be wired to btnSkip.Click in the Designer
|
|
public void btnSkip_Click(object? sender, EventArgs e)
|
|
{
|
|
if (!_pianobarManager.IsConnected)
|
|
{
|
|
MessageBox.Show("Not connected to Pianobar.", "Not Connected",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
_pianobarManager.Skip();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Failed to skip track:\n{ex.Message}", "Command Error",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
// This method should be wired to btnStations.Click in the Designer (or menu item)
|
|
public void btnStations_Click(object? sender, EventArgs e)
|
|
{
|
|
if (!_pianobarManager.IsConnected)
|
|
{
|
|
MessageBox.Show("Not connected to Pianobar.", "Not Connected",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
return;
|
|
}
|
|
|
|
var stationForm = new StationForm(_pianobarManager);
|
|
stationForm.ShowDialog(this);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Menu Event Handlers
|
|
|
|
// This method should be wired to the Settings menu item click
|
|
public void menuSettings_Click(object? sender, EventArgs e)
|
|
{
|
|
var activeProfile = _profileManager.GetActiveProfile();
|
|
var settingsForm = new SettingsForm(_profileManager, activeProfile?.Settings ?? new ProfileSettings());
|
|
if (settingsForm.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
// Settings were saved, restart output manager if connected
|
|
if (_pianobarManager.IsConnected)
|
|
{
|
|
RestartOutputManager();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProfileManager_ProfilesChanged(object? sender, EventArgs e)
|
|
{
|
|
UpdateProfilesMenu();
|
|
}
|
|
|
|
private void ProfileManager_ActiveProfileChanged(object? sender, EventArgs e)
|
|
{
|
|
UpdateProfilesMenu();
|
|
UpdateCenterStatus();
|
|
}
|
|
|
|
// Call this method to build the Profiles submenu dynamically
|
|
private void UpdateProfilesMenu()
|
|
{
|
|
// Assumes menuProfiles (profilesToolStripMenuItem) is a ToolStripMenuItem in your File menu
|
|
// Created in the Designer
|
|
if (profilesToolStripMenuItem == null)
|
|
return;
|
|
|
|
profilesToolStripMenuItem.DropDownItems.Clear();
|
|
|
|
foreach (var profile in _profileManager.Profiles)
|
|
{
|
|
var menuItem = new ToolStripMenuItem(profile.Name);
|
|
menuItem.Tag = profile.Name;
|
|
menuItem.Click += ProfileMenuItem_Click;
|
|
|
|
if (profile.Name == _profileManager.ActiveProfileName)
|
|
menuItem.Checked = true;
|
|
|
|
profilesToolStripMenuItem.DropDownItems.Add(menuItem);
|
|
}
|
|
}
|
|
|
|
private void ProfileMenuItem_Click(object? sender, EventArgs e)
|
|
{
|
|
if (sender is ToolStripMenuItem menuItem && menuItem.Tag is string profileName)
|
|
{
|
|
_profileManager.SetActiveProfile(profileName);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Pianobar Event Handlers
|
|
|
|
private void PianobarManager_Connected(object? sender, EventArgs e)
|
|
{
|
|
Invoke(() =>
|
|
{
|
|
var activeProfile = _profileManager.GetActiveProfile();
|
|
if (activeProfile != null)
|
|
{
|
|
_outputManager = new OutputManager(activeProfile.Settings);
|
|
_outputManager.ActiveStateChanged += OutputManager_ActiveStateChanged;
|
|
_outputManager.Start();
|
|
}
|
|
|
|
UpdateConnectionStatus(
|
|
_outputManager?.IsActive == true ? ConnectionStatus.ConnectedActive : ConnectionStatus.ConnectedIdle
|
|
);
|
|
UpdatePlayPauseButton();
|
|
});
|
|
}
|
|
|
|
private void PianobarManager_Disconnected(object? sender, EventArgs e)
|
|
{
|
|
Invoke(() =>
|
|
{
|
|
_outputManager?.Stop();
|
|
_outputManager = null;
|
|
UpdateConnectionStatus(ConnectionStatus.Disconnected);
|
|
UpdatePlayPauseButton();
|
|
});
|
|
}
|
|
|
|
private void PianobarManager_SongChanged(object? sender, SongChangedEventArgs e)
|
|
{
|
|
Invoke(() =>
|
|
{
|
|
_outputManager?.UpdateSongMetadata(e);
|
|
});
|
|
}
|
|
|
|
private void PianobarManager_StationChanged(object? sender, string e)
|
|
{
|
|
// Station change is handled via event feed
|
|
UpdateCenterStatus();
|
|
}
|
|
|
|
private void PianobarManager_EventOccurred(object? sender, PianobarEventArgs e)
|
|
{
|
|
Invoke(() =>
|
|
{
|
|
// Update right status zone with event text
|
|
if (statusLabelRight != null)
|
|
{
|
|
statusLabelRight.Text = e.EventText;
|
|
}
|
|
});
|
|
}
|
|
|
|
private void OutputManager_ActiveStateChanged(object? sender, EventArgs e)
|
|
{
|
|
Invoke(() =>
|
|
{
|
|
if (_pianobarManager.IsConnected)
|
|
{
|
|
UpdateConnectionStatus(
|
|
_outputManager?.IsActive == true ? ConnectionStatus.ConnectedActive : ConnectionStatus.ConnectedIdle
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region UI Update Methods
|
|
|
|
private void UpdateConnectionStatus(ConnectionStatus status)
|
|
{
|
|
_currentStatus = status;
|
|
|
|
if (statusLabelLeft == null)
|
|
return;
|
|
|
|
switch (status)
|
|
{
|
|
case ConnectionStatus.Disconnected:
|
|
statusLabelLeft.Text = "? Disconnected";
|
|
statusLabelLeft.ForeColor = Color.Red;
|
|
break;
|
|
case ConnectionStatus.ConnectedIdle:
|
|
statusLabelLeft.Text = "? Connected (Idle)";
|
|
statusLabelLeft.ForeColor = Color.Green;
|
|
break;
|
|
case ConnectionStatus.ConnectedActive:
|
|
statusLabelLeft.Text = "? Connected (Active)";
|
|
statusLabelLeft.ForeColor = Color.Blue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void UpdatePlayPauseButton()
|
|
{
|
|
// Uses btnPlayPause from the Designer
|
|
if (btnPlayPause == null)
|
|
return;
|
|
|
|
if (!_pianobarManager.IsConnected)
|
|
{
|
|
btnPlayPause.Text = "Play";
|
|
return;
|
|
}
|
|
|
|
btnPlayPause.Text = _pianobarManager.IsPlaying ? "Pause" : "Play";
|
|
}
|
|
|
|
private void StatusTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
_statusToggle = !_statusToggle;
|
|
UpdateCenterStatus();
|
|
}
|
|
|
|
private void UpdateCenterStatus()
|
|
{
|
|
if (statusLabelCenter == null)
|
|
return;
|
|
|
|
if (_statusToggle)
|
|
{
|
|
// Show profile
|
|
string profileName = _profileManager.ActiveProfileName ?? "None";
|
|
statusLabelCenter.Text = $"Profile: {profileName}";
|
|
}
|
|
else
|
|
{
|
|
// Show station
|
|
string station = _pianobarManager.CurrentStation ?? "None";
|
|
statusLabelCenter.Text = $"Station: {station}";
|
|
}
|
|
}
|
|
|
|
private void RestartOutputManager()
|
|
{
|
|
_outputManager?.Stop();
|
|
|
|
var activeProfile = _profileManager.GetActiveProfile();
|
|
if (activeProfile != null && _pianobarManager.IsConnected)
|
|
{
|
|
_outputManager = new OutputManager(activeProfile.Settings);
|
|
_outputManager.ActiveStateChanged += OutputManager_ActiveStateChanged;
|
|
_outputManager.Start();
|
|
|
|
UpdateConnectionStatus(
|
|
_outputManager.IsActive ? ConnectionStatus.ConnectedActive : ConnectionStatus.ConnectedIdle
|
|
);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Cleanup
|
|
|
|
protected override void OnFormClosing(FormClosingEventArgs e)
|
|
{
|
|
_statusTimer?.Stop();
|
|
_pianobarManager?.Disconnect();
|
|
_outputManager?.Dispose();
|
|
base.OnFormClosing(e);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|