Drop the Options dialog's page banner
It only repeated the page selected in the sidebar, and took vertical space from the page itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,82 +0,0 @@
|
||||
package com.ts3client.ui;
|
||||
|
||||
import com.formdev.flatlaf.util.ScaledEmptyBorder;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
/**
|
||||
* The heading over an Options page: its title and subtitle on an accent-tinted band, with
|
||||
* the page's icon at the far end, after TS3's blue page banners.
|
||||
*/
|
||||
final class OptionsBanner extends JPanel {
|
||||
|
||||
private final JLabel title = new JLabel() {
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
Font base = UIManager.getFont("Label.font");
|
||||
if (base != null) setFont(base.deriveFont(Font.BOLD, base.getSize2D() * 1.4f));
|
||||
}
|
||||
};
|
||||
private final JLabel subtitle = new JLabel();
|
||||
private final JLabel icon = new JLabel();
|
||||
private OptionsPage page;
|
||||
|
||||
OptionsBanner() {
|
||||
super(new BorderLayout(UIScale.scale(12), 0));
|
||||
setOpaque(false);
|
||||
setBorder(new ScaledEmptyBorder(8, 12, 8, 12));
|
||||
|
||||
JPanel text = new JPanel();
|
||||
text.setOpaque(false);
|
||||
text.setLayout(new BoxLayout(text, BoxLayout.Y_AXIS));
|
||||
text.add(title);
|
||||
text.add(subtitle);
|
||||
add(text, BorderLayout.CENTER);
|
||||
add(icon, BorderLayout.EAST);
|
||||
}
|
||||
|
||||
void show(OptionsPage page) {
|
||||
this.page = page;
|
||||
title.setText(page.title());
|
||||
subtitle.setText(page.subtitle());
|
||||
subtitle.setVisible(page.subtitle() != null && !page.subtitle().isEmpty());
|
||||
refreshIcon();
|
||||
}
|
||||
|
||||
/** Picks the icon up again from the active pack, after it changed. */
|
||||
void refreshIcon() {
|
||||
icon.setIcon(page == null ? null : page.icon(UIScale.scale(OptionsSidebar.ICON_SIZE)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Color accent = UIManager.getColor("Component.accentColor");
|
||||
if (accent == null) accent = UIManager.getColor("List.selectionBackground");
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2.setPaint(new GradientPaint(0, 0, withAlpha(accent, 70), 0, getHeight(), withAlpha(accent, 20)));
|
||||
int arc = UIScale.scale(8);
|
||||
g2.fillRoundRect(0, 0, getWidth(), getHeight(), arc, arc);
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
private static Color withAlpha(Color c, int alpha) {
|
||||
return new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,14 @@ import javax.swing.JComponent;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* One page of the Options dialog, as the sidebar lists it and the banner introduces it.
|
||||
* One page of the Options dialog, as the sidebar lists it.
|
||||
*
|
||||
* @param iconKeys TeamSpeak icon keys to try in turn, since packs differ in what they ship
|
||||
*/
|
||||
record OptionsPage(String title, String subtitle, List<String> iconKeys, JComponent content) {
|
||||
record OptionsPage(String title, List<String> iconKeys, JComponent content) {
|
||||
|
||||
OptionsPage(String title, String subtitle, JComponent content, String... iconKeys) {
|
||||
this(title, subtitle, List.of(iconKeys), content);
|
||||
OptionsPage(String title, JComponent content, String... iconKeys) {
|
||||
this(title, List.of(iconKeys), content);
|
||||
}
|
||||
|
||||
/** @return the page's icon at {@code size} pixels, or {@code null} when the pack has none */
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Options dialog, laid out like TS3's: a sidebar of pages on the left, the chosen page
|
||||
* under its banner on the right, OK/Cancel/Apply below. Each page owns its controls and
|
||||
* on the right, OK/Cancel/Apply below. Each page owns its controls and
|
||||
* writes {@link Settings} when applied; this class wires the audio pages, which preview
|
||||
* themselves live against the running audio subsystem, and owns the apply plumbing.
|
||||
*/
|
||||
@@ -68,26 +68,16 @@ public final class SettingsDialog extends JDialog {
|
||||
chatLogsPanel = new ChatLogsPanel(settings);
|
||||
|
||||
List<OptionsPage> pages = List.of(
|
||||
new OptionsPage("Application", "General Application Options", scrollable(applicationPanel),
|
||||
"SETTINGS"),
|
||||
new OptionsPage("myTeamSpeak", "Account and Synchronization", myTeamSpeak,
|
||||
"MYTS_ACCOUNT"),
|
||||
new OptionsPage("Playback", "Configure the Playback Sound System", scrollable(playbackPanel),
|
||||
"PLAYBACK"),
|
||||
new OptionsPage("Capture", "Configure the Capture Sound System", scrollable(capturePanel),
|
||||
"CAPTURE"),
|
||||
new OptionsPage("Design", "Configure the Design of TeamSpeak", designPanel,
|
||||
"GUISETUP", "CHANNEL_EDIT"),
|
||||
new OptionsPage("Hotkeys", "Configure Hotkeys", hotkeysPanel,
|
||||
"HOTKEYS"),
|
||||
new OptionsPage("Contacts", "Configure Contacts and Whispers", scrollable(contactsPanel),
|
||||
"CONTACT", "EDIT_FRIEND_FOE_STATUS"),
|
||||
new OptionsPage("Chat", "Configure the Chat Tabs", scrollable(chatLogsPanel),
|
||||
"CHANNEL_CHAT", "PLAYER_CHAT"),
|
||||
new OptionsPage("Notifications", "Configure the Notifications", notificationsPanel,
|
||||
"NOTIFICATIONS"));
|
||||
new OptionsPage("Application", scrollable(applicationPanel), "SETTINGS"),
|
||||
new OptionsPage("myTeamSpeak", myTeamSpeak, "MYTS_ACCOUNT"),
|
||||
new OptionsPage("Playback", scrollable(playbackPanel), "PLAYBACK"),
|
||||
new OptionsPage("Capture", scrollable(capturePanel), "CAPTURE"),
|
||||
new OptionsPage("Design", designPanel, "GUISETUP", "CHANNEL_EDIT"),
|
||||
new OptionsPage("Hotkeys", hotkeysPanel, "HOTKEYS"),
|
||||
new OptionsPage("Contacts", scrollable(contactsPanel), "CONTACT", "EDIT_FRIEND_FOE_STATUS"),
|
||||
new OptionsPage("Chat", scrollable(chatLogsPanel), "CHANNEL_CHAT", "PLAYER_CHAT"),
|
||||
new OptionsPage("Notifications", notificationsPanel, "NOTIFICATIONS"));
|
||||
|
||||
OptionsBanner banner = new OptionsBanner();
|
||||
CardLayout cards = new CardLayout();
|
||||
JPanel content = new JPanel(cards);
|
||||
for (OptionsPage page : pages) content.add(page.content(), page.title());
|
||||
@@ -96,7 +86,6 @@ public final class SettingsDialog extends JDialog {
|
||||
sidebar.addListSelectionListener(e -> {
|
||||
OptionsPage page = sidebar.getSelectedValue();
|
||||
if (page == null) return;
|
||||
banner.show(page);
|
||||
cards.show(content, page.title());
|
||||
lastPage = sidebar.getSelectedIndex();
|
||||
});
|
||||
@@ -104,23 +93,16 @@ public final class SettingsDialog extends JDialog {
|
||||
JScrollPane sidebarScroll = new JScrollPane(sidebar,
|
||||
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
JPanel page = new JPanel(new BorderLayout(0, UIScale.scale(4)));
|
||||
page.add(banner, BorderLayout.NORTH);
|
||||
page.add(content, BorderLayout.CENTER);
|
||||
|
||||
JPanel body = new JPanel(new BorderLayout(UIScale.scale(8), 0));
|
||||
body.setBorder(new ScaledEmptyBorder(10, 10, 0, 10));
|
||||
body.add(sidebarScroll, BorderLayout.WEST);
|
||||
body.add(page, BorderLayout.CENTER);
|
||||
body.add(content, BorderLayout.CENTER);
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
getContentPane().add(body, BorderLayout.CENTER);
|
||||
getContentPane().add(buildButtons(), BorderLayout.SOUTH);
|
||||
|
||||
Runnable iconsChanged = () -> SwingUtilities.invokeLater(() -> {
|
||||
sidebar.repaint();
|
||||
banner.refreshIcon();
|
||||
});
|
||||
Runnable iconsChanged = () -> SwingUtilities.invokeLater(sidebar::repaint);
|
||||
IconTheme.get().addListener(iconsChanged);
|
||||
|
||||
// The microphone test hears typing too, so typing attenuation can be tried out here.
|
||||
|
||||
Reference in New Issue
Block a user