namespace VoiceCat.App.Forms; partial class MainForm { private System.ComponentModel.IContainer components = null!; // 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!; // Right panel: chat transcript, compose row, activity log private TableLayoutPanel tblRight = null!; private Label lblChat = null!; private RichTextBox rtbChat = null!; private TableLayoutPanel tblCompose = null!; private ComboBox cboScope = null!; private TextBox txtCompose = null!; private Button btnSend = null!; private Label lblActivity = null!; private ListBox lstActivity = null!; // Voice control panel (docked Bottom) private Panel pnlVoice = null!; private FlowLayoutPanel flpVoiceTop = null!; private FlowLayoutPanel flpVoiceBottom = null!; private Button btnMicToggle = null!; private CheckBox chkMute = null!; private CheckBox chkDeafen = null!; private RadioButton radioVad = null!; private RadioButton radioPtt = null!; private RadioButton radioAlwaysOn = null!; private Label lblPttKey = null!; private Button btnChangePtt = null!; private Label lblInputDevice = null!; private ComboBox cboInputDevice = null!; private Button btnRefreshDevices = null!; private Label lblLevel = null!; private ProgressBar pbLevel = null!; private Label lblVadThreshold = null!; private TrackBar trkVadThreshold = 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(); lblChat = new Label(); rtbChat = new RichTextBox(); tblCompose = new TableLayoutPanel(); cboScope = new ComboBox(); txtCompose = new TextBox(); btnSend = new Button(); lblActivity = new Label(); lstActivity = new ListBox(); pnlVoice = new Panel(); flpVoiceTop = new FlowLayoutPanel(); flpVoiceBottom = new FlowLayoutPanel(); btnMicToggle = new Button(); chkMute = new CheckBox(); chkDeafen = new CheckBox(); radioVad = new RadioButton(); radioPtt = new RadioButton(); radioAlwaysOn = new RadioButton(); lblPttKey = new Label(); btnChangePtt = new Button(); lblInputDevice = new Label(); cboInputDevice = new ComboBox(); btnRefreshDevices = new Button(); lblLevel = new Label(); pbLevel = new ProgressBar(); lblVadThreshold = new Label(); trkVadThreshold = new TrackBar(); // ── 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; splitLeft.Panel1.Controls.Add(tvChannels); splitLeft.Panel1.Controls.Add(lblChannels); splitLeft.Panel2.Controls.Add(lstUsers); splitLeft.Panel2.Controls.Add(lblUsers); // ── Chat transcript ─────────────────────────────────────────────────── lblChat.Text = "Chat:"; lblChat.AutoSize = true; lblChat.Padding = new Padding(2, 2, 2, 1); rtbChat.AccessibleName = "Chat transcript"; rtbChat.AccessibleDescription = "History of channel and private messages."; rtbChat.Dock = DockStyle.Fill; rtbChat.ReadOnly = true; rtbChat.ScrollBars = RichTextBoxScrollBars.Vertical; rtbChat.BackColor = SystemColors.Window; rtbChat.TabIndex = 0; // ── Compose row ─────────────────────────────────────────────────────── cboScope.AccessibleName = "Send to"; cboScope.AccessibleDescription = "Choose Channel to send to everyone, or a specific user for a private message."; cboScope.DropDownStyle = ComboBoxStyle.DropDownList; cboScope.Dock = DockStyle.Fill; cboScope.TabIndex = 1; txtCompose.AccessibleName = "Message text"; txtCompose.AccessibleDescription = "Type your message. Press Enter or click Send to send."; txtCompose.Dock = DockStyle.Fill; txtCompose.TabIndex = 2; btnSend.Text = "&Send"; btnSend.Dock = DockStyle.Fill; btnSend.TabIndex = 3; tblCompose.ColumnCount = 3; tblCompose.RowCount = 1; tblCompose.Dock = DockStyle.Fill; tblCompose.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 165F)); 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); tblCompose.Controls.Add(cboScope, 0, 0); tblCompose.Controls.Add(txtCompose, 1, 0); tblCompose.Controls.Add(btnSend, 2, 0); // ── Activity log ────────────────────────────────────────────────────── lblActivity.Text = "Activity:"; lblActivity.AutoSize = true; lblActivity.Padding = new Padding(2, 4, 2, 1); lstActivity.AccessibleName = "Activity log"; lstActivity.AccessibleDescription = "Record of joins, leaves, talk-state changes, and server messages."; lstActivity.Dock = DockStyle.Fill; lstActivity.HorizontalScrollbar = true; lstActivity.TabIndex = 4; // ── Right table layout ──────────────────────────────────────────────── tblRight.ColumnCount = 1; tblRight.RowCount = 5; tblRight.Dock = DockStyle.Fill; tblRight.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); tblRight.RowStyles.Add(new RowStyle(SizeType.AutoSize)); tblRight.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); tblRight.RowStyles.Add(new RowStyle(SizeType.Absolute, 34F)); tblRight.RowStyles.Add(new RowStyle(SizeType.AutoSize)); tblRight.RowStyles.Add(new RowStyle(SizeType.Absolute, 120F)); tblRight.Controls.Add(lblChat, 0, 0); tblRight.Controls.Add(rtbChat, 0, 1); tblRight.Controls.Add(tblCompose, 0, 2); tblRight.Controls.Add(lblActivity, 0, 3); tblRight.Controls.Add(lstActivity, 0, 4); // ── Main split ──────────────────────────────────────────────────────── // SplitterDistance set in OnLoad — see MainForm.cs. splitMain.Dock = DockStyle.Fill; splitMain.Panel1MinSize = 150; splitMain.TabIndex = 1; splitMain.Panel1.Controls.Add(splitLeft); splitMain.Panel2.Controls.Add(tblRight); // ── Voice control panel ─────────────────────────────────────────────── // Top row: mic start/stop, mute/deafen, VAD/PTT btnMicToggle.Text = "&Join Voice"; btnMicToggle.AutoSize = true; btnMicToggle.Margin = new Padding(0, 2, 6, 0); btnMicToggle.TabIndex = 0; 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; var lblMode = new Label { Text = "Mode:", AutoSize = true, Margin = new Padding(0, 5, 4, 0) }; radioVad.Text = "&Voice activation"; radioVad.AutoSize = true; radioVad.Checked = true; radioVad.Enabled = false; radioVad.Margin = new Padding(0, 4, 6, 0); radioVad.TabIndex = 3; radioPtt.Text = "&Push to talk"; radioPtt.AutoSize = true; radioPtt.Enabled = false; radioPtt.Margin = new Padding(0, 4, 4, 0); radioPtt.TabIndex = 4; radioAlwaysOn.Text = "A&lways on"; radioAlwaysOn.AutoSize = true; radioAlwaysOn.Enabled = false; radioAlwaysOn.Margin = new Padding(0, 4, 12, 0); radioAlwaysOn.TabIndex = 5; lblPttKey.Text = "(F8)"; lblPttKey.AutoSize = true; lblPttKey.Margin = new Padding(2, 5, 4, 0); lblPttKey.Visible = false; btnChangePtt.Text = "Change key..."; btnChangePtt.AutoSize = true; btnChangePtt.Margin = new Padding(0, 2, 0, 0); btnChangePtt.Visible = false; btnChangePtt.TabIndex = 6; flpVoiceTop.Dock = DockStyle.Top; flpVoiceTop.Height = 34; flpVoiceTop.AutoSize = false; flpVoiceTop.Padding = new Padding(4, 2, 4, 0); flpVoiceTop.Controls.Add(btnMicToggle); flpVoiceTop.Controls.Add(chkMute); flpVoiceTop.Controls.Add(chkDeafen); flpVoiceTop.Controls.Add(lblMode); flpVoiceTop.Controls.Add(radioVad); flpVoiceTop.Controls.Add(radioPtt); flpVoiceTop.Controls.Add(radioAlwaysOn); flpVoiceTop.Controls.Add(lblPttKey); flpVoiceTop.Controls.Add(btnChangePtt); // Bottom row: device picker + level meter lblInputDevice.Text = "Input:"; lblInputDevice.AutoSize = true; lblInputDevice.Margin = new Padding(0, 5, 4, 0); cboInputDevice.AccessibleName = "Input device"; cboInputDevice.AccessibleDescription = "Select which microphone or audio device to use."; cboInputDevice.DropDownStyle = ComboBoxStyle.DropDownList; cboInputDevice.Width = 200; cboInputDevice.Margin = new Padding(0, 2, 4, 0); cboInputDevice.TabIndex = 7; btnRefreshDevices.Text = "Re&fresh"; btnRefreshDevices.AutoSize = true; btnRefreshDevices.Margin = new Padding(0, 2, 12, 0); btnRefreshDevices.TabIndex = 8; lblLevel.Text = "Level:"; lblLevel.AutoSize = true; lblLevel.Margin = new Padding(0, 5, 4, 0); 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; pbLevel.TabStop = false; // informational, not actionable lblVadThreshold.Text = "Sensitivity:"; lblVadThreshold.AutoSize = true; lblVadThreshold.Margin = new Padding(12, 5, 4, 0); lblVadThreshold.Visible = true; // shown when VAD mode active trkVadThreshold.AccessibleName = "VAD sensitivity"; trkVadThreshold.AccessibleDescription = "Voice detection sensitivity. Higher = more sensitive (triggers on quieter sounds). " + "Range 1–100; default 25."; trkVadThreshold.Minimum = 1; trkVadThreshold.Maximum = 100; trkVadThreshold.Value = 76; // maps to ~0.024 (≈ default 0.025 threshold) trkVadThreshold.TickFrequency = 10; trkVadThreshold.SmallChange = 1; trkVadThreshold.LargeChange = 10; trkVadThreshold.Width = 120; trkVadThreshold.Margin = new Padding(0, 2, 0, 0); trkVadThreshold.TabIndex = 9; trkVadThreshold.Visible = true; flpVoiceBottom.Dock = DockStyle.Fill; flpVoiceBottom.Padding = new Padding(4, 0, 4, 2); flpVoiceBottom.Controls.Add(lblInputDevice); flpVoiceBottom.Controls.Add(cboInputDevice); flpVoiceBottom.Controls.Add(btnRefreshDevices); flpVoiceBottom.Controls.Add(lblLevel); flpVoiceBottom.Controls.Add(pbLevel); flpVoiceBottom.Controls.Add(lblVadThreshold); flpVoiceBottom.Controls.Add(trkVadThreshold); pnlVoice.Dock = DockStyle.Bottom; pnlVoice.Height = 68; pnlVoice.BorderStyle = BorderStyle.FixedSingle; pnlVoice.Padding = new Padding(0); pnlVoice.Controls.Add(flpVoiceBottom); // Fill — added first pnlVoice.Controls.Add(flpVoiceTop); // Top — added last // ── Form ────────────────────────────────────────────────────────────── AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(960, 680); MinimumSize = new Size(700, 540); KeyPreview = true; // form sees KeyDown/KeyUp before focused control (needed for PTT) // Controls added in reverse docking priority: Fill first, then Bottom, then Top. Controls.Add(splitMain); // DockStyle.Fill Controls.Add(pnlVoice); // DockStyle.Bottom Controls.Add(lblStatus); // DockStyle.Top StartPosition = FormStartPosition.CenterScreen; Text = "VoiceCat"; } }