2026-06-17 00:35:16 +02:00
|
|
|
namespace VoiceCat.App.Forms;
|
|
|
|
|
|
|
|
|
|
partial class MainForm
|
|
|
|
|
{
|
|
|
|
|
private System.ComponentModel.IContainer components = null!;
|
|
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
// Menu bar + toolbar
|
2026-06-17 16:31:29 +02:00
|
|
|
private MenuStrip menuStrip = null!;
|
2026-06-20 14:24:54 +02:00
|
|
|
private ToolStrip toolStrip = null!;
|
|
|
|
|
private ToolStripButton tsbJoinVoice = null!;
|
|
|
|
|
private ToolStripButton tsbScreenShare = null!;
|
2026-06-17 16:31:29 +02:00
|
|
|
|
2026-06-17 00:35:16 +02:00
|
|
|
// Status bar
|
|
|
|
|
private Label lblStatus = null!;
|
|
|
|
|
|
|
|
|
|
// Main left/right split
|
|
|
|
|
private SplitContainer splitMain = null!;
|
|
|
|
|
|
|
|
|
|
// Left panel: channel tree on top, user list on bottom
|
|
|
|
|
private SplitContainer splitLeft = null!;
|
|
|
|
|
private Label lblChannels = null!;
|
|
|
|
|
private TreeView tvChannels = null!;
|
|
|
|
|
private Label lblUsers = null!;
|
|
|
|
|
private ListBox lstUsers = null!;
|
|
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
// Right panel: unified log, compose row, output volume
|
2026-06-17 00:35:16 +02:00
|
|
|
private TableLayoutPanel tblRight = null!;
|
2026-06-20 14:24:54 +02:00
|
|
|
private Label lblLog = null!;
|
|
|
|
|
private RichTextBox rtbLog = null!;
|
2026-06-17 00:35:16 +02:00
|
|
|
private TableLayoutPanel tblCompose = null!;
|
|
|
|
|
private TextBox txtCompose = null!;
|
|
|
|
|
private Button btnSend = null!;
|
2026-06-20 14:24:54 +02:00
|
|
|
private Label lblOutputVolume = null!;
|
|
|
|
|
private TrackBar trkOutputVolume = null!;
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
// Voice control panel (docked Bottom)
|
|
|
|
|
private Panel pnlVoice = null!;
|
|
|
|
|
private FlowLayoutPanel flpVoiceTop = null!;
|
|
|
|
|
private CheckBox chkMute = null!;
|
|
|
|
|
private CheckBox chkDeafen = null!;
|
|
|
|
|
private Label lblLevel = null!;
|
|
|
|
|
private ProgressBar pbLevel = null!;
|
|
|
|
|
|
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
if (disposing) components?.Dispose();
|
|
|
|
|
base.Dispose(disposing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void InitializeComponent()
|
|
|
|
|
{
|
|
|
|
|
components = new System.ComponentModel.Container();
|
|
|
|
|
|
|
|
|
|
lblStatus = new Label();
|
|
|
|
|
splitMain = new SplitContainer();
|
|
|
|
|
splitLeft = new SplitContainer();
|
|
|
|
|
lblChannels = new Label();
|
|
|
|
|
tvChannels = new TreeView();
|
|
|
|
|
lblUsers = new Label();
|
|
|
|
|
lstUsers = new ListBox();
|
|
|
|
|
tblRight = new TableLayoutPanel();
|
2026-06-20 14:24:54 +02:00
|
|
|
lblLog = new Label();
|
|
|
|
|
rtbLog = new RichTextBox();
|
2026-06-17 00:35:16 +02:00
|
|
|
tblCompose = new TableLayoutPanel();
|
|
|
|
|
txtCompose = new TextBox();
|
|
|
|
|
btnSend = new Button();
|
2026-06-20 14:24:54 +02:00
|
|
|
lblOutputVolume = new Label();
|
|
|
|
|
trkOutputVolume = new TrackBar();
|
2026-06-17 00:35:16 +02:00
|
|
|
pnlVoice = new Panel();
|
|
|
|
|
flpVoiceTop = new FlowLayoutPanel();
|
|
|
|
|
chkMute = new CheckBox();
|
|
|
|
|
chkDeafen = new CheckBox();
|
|
|
|
|
lblLevel = new Label();
|
|
|
|
|
pbLevel = new ProgressBar();
|
2026-06-20 14:24:54 +02:00
|
|
|
menuStrip = new MenuStrip();
|
|
|
|
|
toolStrip = new ToolStrip();
|
|
|
|
|
tsbJoinVoice = new ToolStripButton();
|
|
|
|
|
tsbScreenShare = new ToolStripButton();
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
// ── Status label ──────────────────────────────────────────────────────
|
|
|
|
|
lblStatus.AccessibleName = "Connection status";
|
|
|
|
|
lblStatus.Dock = DockStyle.Top;
|
|
|
|
|
lblStatus.AutoSize = true;
|
|
|
|
|
lblStatus.Padding = new Padding(6, 4, 6, 4);
|
|
|
|
|
lblStatus.TabIndex = 0;
|
|
|
|
|
lblStatus.Text = "Connecting...";
|
|
|
|
|
|
|
|
|
|
// ── Channel tree ──────────────────────────────────────────────────────
|
|
|
|
|
lblChannels.Text = "Channels:";
|
|
|
|
|
lblChannels.Dock = DockStyle.Top;
|
|
|
|
|
lblChannels.AutoSize = true;
|
|
|
|
|
lblChannels.Padding = new Padding(4, 4, 4, 2);
|
|
|
|
|
|
|
|
|
|
tvChannels.AccessibleName = "Channel list";
|
|
|
|
|
tvChannels.AccessibleDescription =
|
|
|
|
|
"Double-click or press Enter to join a channel. " +
|
|
|
|
|
"Channels marked [password] require a password.";
|
|
|
|
|
tvChannels.Dock = DockStyle.Fill;
|
|
|
|
|
tvChannels.HideSelection = false;
|
|
|
|
|
tvChannels.TabIndex = 0;
|
|
|
|
|
|
|
|
|
|
// ── User list ─────────────────────────────────────────────────────────
|
|
|
|
|
lblUsers.Text = "Users in channel:";
|
|
|
|
|
lblUsers.Dock = DockStyle.Top;
|
|
|
|
|
lblUsers.AutoSize = true;
|
|
|
|
|
lblUsers.Padding = new Padding(4, 4, 4, 2);
|
|
|
|
|
|
|
|
|
|
lstUsers.AccessibleName = "Users in current channel";
|
|
|
|
|
lstUsers.AccessibleDescription =
|
|
|
|
|
"People in the same channel. Double-click or press Enter for per-user volume settings. " +
|
|
|
|
|
"Talking users are marked (talking).";
|
|
|
|
|
lstUsers.Dock = DockStyle.Fill;
|
|
|
|
|
lstUsers.TabIndex = 1;
|
|
|
|
|
|
|
|
|
|
// ── Left split (channels top, users bottom) ───────────────────────────
|
|
|
|
|
splitLeft.Orientation = Orientation.Horizontal;
|
|
|
|
|
splitLeft.Dock = DockStyle.Fill;
|
|
|
|
|
splitLeft.Panel1MinSize = 100;
|
|
|
|
|
splitLeft.Panel2MinSize = 80;
|
|
|
|
|
splitLeft.TabIndex = 0;
|
2026-06-22 13:34:26 +02:00
|
|
|
// Keep the resize splitter out of the Tab cycle so focus moves control-to-control.
|
|
|
|
|
splitLeft.TabStop = false;
|
|
|
|
|
// Name the otherwise-anonymous "pane" containers so screen readers announce
|
|
|
|
|
// orientation instead of a stack of unnamed panes.
|
|
|
|
|
splitLeft.AccessibleName = "Channels and users";
|
|
|
|
|
splitLeft.Panel1.AccessibleName = "Channels";
|
|
|
|
|
splitLeft.Panel2.AccessibleName = "Users";
|
2026-06-17 00:35:16 +02:00
|
|
|
splitLeft.Panel1.Controls.Add(tvChannels);
|
|
|
|
|
splitLeft.Panel1.Controls.Add(lblChannels);
|
|
|
|
|
splitLeft.Panel2.Controls.Add(lstUsers);
|
|
|
|
|
splitLeft.Panel2.Controls.Add(lblUsers);
|
|
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
// ── Unified log ───────────────────────────────────────────────────────
|
|
|
|
|
lblLog.Text = "Chat & Activity:";
|
|
|
|
|
lblLog.AutoSize = true;
|
|
|
|
|
lblLog.Padding = new Padding(2, 2, 2, 1);
|
2026-06-17 00:35:16 +02:00
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
rtbLog.AccessibleName = "Chat and activity log";
|
|
|
|
|
rtbLog.AccessibleDescription = "Combined history of chat messages (normal) and activity events (gray).";
|
|
|
|
|
rtbLog.Dock = DockStyle.Fill;
|
|
|
|
|
rtbLog.ReadOnly = true;
|
|
|
|
|
rtbLog.ScrollBars = RichTextBoxScrollBars.Vertical;
|
|
|
|
|
rtbLog.BackColor = SystemColors.Window;
|
|
|
|
|
rtbLog.TabIndex = 0;
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
// ── Compose row ───────────────────────────────────────────────────────
|
|
|
|
|
txtCompose.AccessibleName = "Message text";
|
2026-06-20 14:24:54 +02:00
|
|
|
txtCompose.AccessibleDescription = "Type your channel message. Press Enter or click Send to send.";
|
2026-06-17 00:35:16 +02:00
|
|
|
txtCompose.Dock = DockStyle.Fill;
|
2026-06-20 14:24:54 +02:00
|
|
|
txtCompose.TabIndex = 1;
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
btnSend.Text = "&Send";
|
|
|
|
|
btnSend.Dock = DockStyle.Fill;
|
2026-06-20 14:24:54 +02:00
|
|
|
btnSend.TabIndex = 2;
|
2026-06-17 00:35:16 +02:00
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
tblCompose.ColumnCount = 2;
|
2026-06-17 00:35:16 +02:00
|
|
|
tblCompose.RowCount = 1;
|
|
|
|
|
tblCompose.Dock = DockStyle.Fill;
|
|
|
|
|
tblCompose.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
|
|
|
|
tblCompose.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 68F));
|
|
|
|
|
tblCompose.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
|
|
|
|
tblCompose.Padding = new Padding(0, 3, 0, 0);
|
2026-06-20 14:24:54 +02:00
|
|
|
tblCompose.Controls.Add(txtCompose, 0, 0);
|
|
|
|
|
tblCompose.Controls.Add(btnSend, 1, 0);
|
2026-06-17 00:35:16 +02:00
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
// ── Output volume row ─────────────────────────────────────────────────
|
|
|
|
|
lblOutputVolume.Text = "Output volume:";
|
|
|
|
|
lblOutputVolume.AutoSize = true;
|
|
|
|
|
lblOutputVolume.Padding = new Padding(2, 6, 4, 0);
|
2026-06-17 00:35:16 +02:00
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
trkOutputVolume.AccessibleName = "Output volume";
|
|
|
|
|
trkOutputVolume.AccessibleDescription = "Global playback volume for all incoming audio.";
|
|
|
|
|
trkOutputVolume.Minimum = 0;
|
|
|
|
|
trkOutputVolume.Maximum = 100;
|
|
|
|
|
trkOutputVolume.Value = 80;
|
|
|
|
|
trkOutputVolume.TickFrequency = 10;
|
|
|
|
|
trkOutputVolume.SmallChange = 1;
|
|
|
|
|
trkOutputVolume.LargeChange = 10;
|
|
|
|
|
trkOutputVolume.Dock = DockStyle.Fill;
|
|
|
|
|
trkOutputVolume.TabIndex = 3;
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
// ── Right table layout ────────────────────────────────────────────────
|
|
|
|
|
tblRight.ColumnCount = 1;
|
|
|
|
|
tblRight.RowCount = 5;
|
|
|
|
|
tblRight.Dock = DockStyle.Fill;
|
|
|
|
|
tblRight.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
2026-06-20 14:24:54 +02:00
|
|
|
tblRight.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // row 0: lblLog
|
|
|
|
|
tblRight.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); // row 1: rtbLog
|
|
|
|
|
tblRight.RowStyles.Add(new RowStyle(SizeType.Absolute, 34F)); // row 2: compose
|
|
|
|
|
tblRight.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // row 3: vol label
|
|
|
|
|
tblRight.RowStyles.Add(new RowStyle(SizeType.Absolute, 45F)); // row 4: vol slider
|
|
|
|
|
tblRight.Controls.Add(lblLog, 0, 0);
|
|
|
|
|
tblRight.Controls.Add(rtbLog, 0, 1);
|
2026-06-17 00:35:16 +02:00
|
|
|
tblRight.Controls.Add(tblCompose, 0, 2);
|
2026-06-20 14:24:54 +02:00
|
|
|
tblRight.Controls.Add(lblOutputVolume, 0, 3);
|
|
|
|
|
tblRight.Controls.Add(trkOutputVolume, 0, 4);
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
// ── Main split ────────────────────────────────────────────────────────
|
|
|
|
|
splitMain.Dock = DockStyle.Fill;
|
|
|
|
|
splitMain.Panel1MinSize = 150;
|
|
|
|
|
splitMain.TabIndex = 1;
|
2026-06-22 13:34:26 +02:00
|
|
|
splitMain.TabStop = false;
|
|
|
|
|
splitMain.AccessibleName = "Main";
|
|
|
|
|
splitMain.Panel1.AccessibleName = "Channels and users";
|
|
|
|
|
splitMain.Panel2.AccessibleName = "Chat and activity";
|
2026-06-17 00:35:16 +02:00
|
|
|
splitMain.Panel1.Controls.Add(splitLeft);
|
|
|
|
|
splitMain.Panel2.Controls.Add(tblRight);
|
|
|
|
|
|
|
|
|
|
// ── Voice control panel ───────────────────────────────────────────────
|
|
|
|
|
chkMute.Text = "&Mute mic";
|
|
|
|
|
chkMute.AutoSize = true;
|
|
|
|
|
chkMute.Enabled = false;
|
|
|
|
|
chkMute.Margin = new Padding(0, 4, 6, 0);
|
|
|
|
|
chkMute.TabIndex = 1;
|
|
|
|
|
|
|
|
|
|
chkDeafen.Text = "&Deafen";
|
|
|
|
|
chkDeafen.AutoSize = true;
|
|
|
|
|
chkDeafen.Enabled = false;
|
|
|
|
|
chkDeafen.Margin = new Padding(0, 4, 12, 0);
|
|
|
|
|
chkDeafen.TabIndex = 2;
|
|
|
|
|
|
2026-06-23 12:15:18 +02:00
|
|
|
flpVoiceTop.Dock = DockStyle.Fill;
|
2026-06-17 00:35:16 +02:00
|
|
|
flpVoiceTop.AutoSize = false;
|
|
|
|
|
flpVoiceTop.Padding = new Padding(4, 2, 4, 0);
|
|
|
|
|
flpVoiceTop.Controls.Add(chkMute);
|
|
|
|
|
flpVoiceTop.Controls.Add(chkDeafen);
|
|
|
|
|
|
|
|
|
|
lblLevel.Text = "Level:";
|
|
|
|
|
lblLevel.AutoSize = true;
|
2026-06-23 12:15:18 +02:00
|
|
|
lblLevel.Margin = new Padding(12, 5, 4, 0);
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
pbLevel.AccessibleName = "Microphone level";
|
|
|
|
|
pbLevel.AccessibleDescription = "Current input level from the microphone.";
|
|
|
|
|
pbLevel.Width = 120;
|
|
|
|
|
pbLevel.Height = 16;
|
|
|
|
|
pbLevel.Maximum = 100;
|
|
|
|
|
pbLevel.Margin = new Padding(0, 6, 0, 0);
|
|
|
|
|
pbLevel.Style = ProgressBarStyle.Continuous;
|
2026-06-20 14:24:54 +02:00
|
|
|
pbLevel.TabStop = false;
|
2026-06-17 00:35:16 +02:00
|
|
|
|
2026-06-23 12:15:18 +02:00
|
|
|
flpVoiceTop.Controls.Add(lblLevel);
|
|
|
|
|
flpVoiceTop.Controls.Add(pbLevel);
|
2026-06-17 00:35:16 +02:00
|
|
|
|
|
|
|
|
pnlVoice.Dock = DockStyle.Bottom;
|
2026-06-23 12:15:18 +02:00
|
|
|
pnlVoice.Height = 38;
|
2026-06-17 00:35:16 +02:00
|
|
|
pnlVoice.BorderStyle = BorderStyle.FixedSingle;
|
|
|
|
|
pnlVoice.Padding = new Padding(0);
|
2026-06-23 12:15:18 +02:00
|
|
|
pnlVoice.Controls.Add(flpVoiceTop);
|
2026-06-17 00:35:16 +02:00
|
|
|
|
2026-06-20 14:24:54 +02:00
|
|
|
// ── Toolbar ───────────────────────────────────────────────────────────
|
|
|
|
|
tsbJoinVoice.Text = "Join Voice";
|
|
|
|
|
tsbJoinVoice.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
|
|
|
|
tsbJoinVoice.CheckOnClick = false;
|
|
|
|
|
|
|
|
|
|
tsbScreenShare.Text = "Share Screen Audio";
|
|
|
|
|
tsbScreenShare.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
|
|
|
|
tsbScreenShare.CheckOnClick = false;
|
|
|
|
|
|
|
|
|
|
toolStrip.Dock = DockStyle.Top;
|
|
|
|
|
toolStrip.Items.Add(tsbJoinVoice);
|
|
|
|
|
toolStrip.Items.Add(new ToolStripSeparator());
|
|
|
|
|
toolStrip.Items.Add(tsbScreenShare);
|
|
|
|
|
toolStrip.TabIndex = 1;
|
|
|
|
|
toolStrip.AccessibleName = "Toolbar";
|
|
|
|
|
|
2026-06-17 16:31:29 +02:00
|
|
|
// ── Menu strip ────────────────────────────────────────────────────────
|
|
|
|
|
menuStrip.AccessibleName = "Main menu";
|
|
|
|
|
menuStrip.Dock = DockStyle.Top;
|
|
|
|
|
menuStrip.TabIndex = 0;
|
|
|
|
|
MainMenuStrip = menuStrip;
|
|
|
|
|
|
2026-06-17 00:35:16 +02:00
|
|
|
// ── Form ──────────────────────────────────────────────────────────────
|
|
|
|
|
AutoScaleMode = AutoScaleMode.Font;
|
|
|
|
|
ClientSize = new Size(960, 680);
|
|
|
|
|
MinimumSize = new Size(700, 540);
|
2026-06-20 14:24:54 +02:00
|
|
|
KeyPreview = true;
|
|
|
|
|
Controls.Add(splitMain); // DockStyle.Fill
|
|
|
|
|
Controls.Add(pnlVoice); // DockStyle.Bottom
|
|
|
|
|
Controls.Add(lblStatus); // DockStyle.Top
|
|
|
|
|
Controls.Add(toolStrip); // DockStyle.Top (above status)
|
|
|
|
|
Controls.Add(menuStrip); // DockStyle.Top (topmost)
|
2026-06-17 00:35:16 +02:00
|
|
|
StartPosition = FormStartPosition.CenterScreen;
|
|
|
|
|
Text = "VoiceCat";
|
|
|
|
|
}
|
|
|
|
|
}
|