Lay out the Options dialog like TeamSpeak 3's

A sidebar of pages with large icons replaces the tabs, and each page
opens under a banner with its title, subtitle and icon. OK, Cancel and
Apply sit below, and the dialog reopens on the last page used.

The pages follow TS3's: Application (muted-microphone warning, reported
client version), myTeamSpeak, Playback, Capture, Design, Hotkeys,
Contacts, Chat and Notifications. Capture now holds everything from the
microphone to the server: the device and gain, activation with the
microphone test, signal processing and the encoder, laid out in one
grid so its columns line up. Forms are grouped under section headings.

Cancel now goes back to what was last applied, and closing the window
cancels too, so a theme or icon pack being tried out is put back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 17:07:13 +00:00
parent 0ad56671af
commit e06bb82299
19 changed files with 903 additions and 505 deletions

View File

@@ -1,7 +1,5 @@
package com.ts3client.ui;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.formdev.flatlaf.util.UIScale;
import com.ts3client.config.Settings;
import javax.swing.DefaultListCellRenderer;
@@ -13,46 +11,28 @@ import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
/**
* Options page for the contact list: whether friends and blocked clients are
* coloured in the server tree, whose whispers get through (TeamSpeak's whisper
* options), and the defaults a new contact starts with.
*/
final class ContactsPanel extends JPanel {
final class ContactsPanel extends FormPanel {
private final Settings settings;
private final JCheckBox colorContacts = new JCheckBox("Colour friends and blocked clients in the server tree");
private final JComboBox<Settings.WhisperPolicy> whisperPolicy = new JComboBox<>(Settings.WhisperPolicy.values());
ContactsPanel(Settings settings) {
super(new BorderLayout());
this.settings = settings;
setBorder(new ScaledEmptyBorder(12, 12, 12, 12));
GridBagConstraints c = gbc();
JPanel p = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = UIScale.scale(new Insets(2, 2, 2, 2));
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridwidth = 2;
c.gridy = 0;
colorContacts.setSelected(settings.colorContacts);
colorContacts.setToolTipText("Friends in green and blocked clients in red, as the TeamSpeak client shows them");
p.add(colorContacts, c);
c.gridy = 1;
c.insets = UIScale.scale(new Insets(12, 2, 2, 2));
p.add(new JLabel("Whispers: who is allowed to whisper to you"), c);
c.gridy = 2;
c.insets = UIScale.scale(new Insets(2, 2, 2, 2));
whisperPolicy.setSelectedItem(settings.whisperPolicy);
whisperPolicy.setRenderer(new DefaultListCellRenderer() {
@Override
@@ -66,20 +46,24 @@ final class ContactsPanel extends JPanel {
whisperPolicy.setToolTipText("<html>Use individual settings in contacts, else allow: a client not on your "
+ "contact list may whisper to you.<br>Use individual settings in contacts, else deny: only "
+ "contacts marked \"Allow whisper\" may.<br>Nobody: individual contact settings are ignored.</html>");
p.add(whisperPolicy, c);
c.gridy = 3;
c.insets = UIScale.scale(new Insets(12, 2, 2, 2));
c.fill = GridBagConstraints.NONE;
JButton defaults = new JButton("Contact defaults…");
defaults.setToolTipText("Configure default settings when adding a client to the Contact Manager");
defaults.addActionListener(e -> {
java.awt.Window owner = SwingUtilities.getWindowAncestor(this);
new ContactDefaultsDialog(owner instanceof JDialog ? (JDialog) owner : null, settings).setVisible(true);
});
p.add(defaults, c);
JPanel defaultsRow = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
defaultsRow.add(defaults);
add(p, BorderLayout.NORTH);
int row = 0;
addSection(this, c, row++, "Server Tree");
addWide(this, c, row++, colorContacts);
addSection(this, c, row++, "Whispers");
addRow(this, c, row++, new JLabel("Allow whispers from:"), whisperPolicy);
addSection(this, c, row++, "New Contacts");
addWide(this, c, row++, defaultsRow);
addFiller(this, c, row);
}
/** Copies the page into the settings; the caller saves them. */