Draw the interface with TeamSpeak icon packs
Icon packs are read in TeamSpeak's own format — a zip (or unpacked folder) of SVG/PNG art plus a settings.ini mapping icon keys to files — so the packs of an installed client and the ones from its add-on site work unchanged. Legacy packs without that mapping (default.zip) are resolved by their file naming convention instead, picking the resolution closest to the drawn size. The pack draws the tree, toolbar, menus, context menus, file browser and the default group icons; a pack's FALLBACK option decides whether what it lacks comes from default.zip, and anything still missing falls back to the icons the client draws itself. Options → Design picks the pack and shows a viewer of everything in it. Vector art is rasterised with JSVG, and the pack search roots are shared with the sound packs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,7 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
private final JLabel statusLabel = new JLabel("Not connected");
|
||||
private final JLabel codecLabel = new JLabel();
|
||||
|
||||
private JToolBar toolbar;
|
||||
private JButton connectButton;
|
||||
private JButton disconnectButton;
|
||||
private JToggleButton activeButton;
|
||||
@@ -108,7 +109,10 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
|
||||
setJMenuBar(buildMenuBar());
|
||||
|
||||
add(buildToolbar(), BorderLayout.NORTH);
|
||||
toolbar = buildToolbar();
|
||||
add(toolbar, BorderLayout.NORTH);
|
||||
// Switching the icon pack in the options dialog re-decorates the whole window.
|
||||
IconTheme.get().addListener(() -> SwingUtilities.invokeLater(this::rebuildIcons));
|
||||
add(tabPane, BorderLayout.CENTER);
|
||||
add(buildStatusBar(), BorderLayout.SOUTH);
|
||||
|
||||
@@ -140,15 +144,15 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
JMenuBar bar = new JMenuBar();
|
||||
|
||||
JMenu connections = new JMenu("Connections");
|
||||
JMenuItem connect = new JMenuItem("Connect…");
|
||||
JMenuItem connect = new JMenuItem("Connect…", Icons.of("CONNECT"));
|
||||
connect.setAccelerator(KeyStroke.getKeyStroke("control S"));
|
||||
connect.addActionListener(e -> showConnectDialog());
|
||||
JMenuItem disconnect = new JMenuItem("Disconnect");
|
||||
JMenuItem disconnect = new JMenuItem("Disconnect", Icons.of("DISCONNECT"));
|
||||
disconnect.addActionListener(e -> doDisconnect());
|
||||
JMenuItem closeTab = new JMenuItem("Close tab");
|
||||
JMenuItem closeTab = new JMenuItem("Close tab", Icons.of("CLOSE_BUTTON"));
|
||||
closeTab.setAccelerator(KeyStroke.getKeyStroke("control W"));
|
||||
closeTab.addActionListener(e -> closeTab(selected));
|
||||
JMenuItem quit = new JMenuItem("Quit");
|
||||
JMenuItem quit = new JMenuItem("Quit", Icons.of("QUIT"));
|
||||
quit.addActionListener(e -> {
|
||||
shutdown();
|
||||
System.exit(0);
|
||||
@@ -163,17 +167,17 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
rebuildBookmarksMenu();
|
||||
|
||||
JMenu self = new JMenu("Self");
|
||||
JMenuItem mute = new JMenuItem("Toggle microphone");
|
||||
JMenuItem mute = new JMenuItem("Toggle microphone", Icons.of("CAPTURE"));
|
||||
mute.addActionListener(e -> micButton.doClick());
|
||||
JMenuItem deaf = new JMenuItem("Toggle speakers");
|
||||
JMenuItem deaf = new JMenuItem("Toggle speakers", Icons.of("PLAYBACK"));
|
||||
deaf.addActionListener(e -> speakerButton.doClick());
|
||||
awayItem = new JCheckBoxMenuItem("Away");
|
||||
awayItem = new JCheckBoxMenuItem("Away", Icons.of("AWAY"), false);
|
||||
awayItem.addActionListener(e -> toggleAway());
|
||||
commanderItem = new JCheckBoxMenuItem("Channel commander");
|
||||
commanderItem = new JCheckBoxMenuItem("Channel commander", Icons.of("CHANNEL_COMMANDER"), false);
|
||||
commanderItem.addActionListener(e -> {
|
||||
if (selected != null) selected.setCommander(commanderItem.isSelected());
|
||||
});
|
||||
JMenuItem nick = new JMenuItem("Change nickname…");
|
||||
JMenuItem nick = new JMenuItem("Change nickname…", Icons.of("CHANGE_NICKNAME"));
|
||||
nick.addActionListener(e -> changeNickname());
|
||||
self.add(mute);
|
||||
self.add(deaf);
|
||||
@@ -184,16 +188,16 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
self.add(nick);
|
||||
|
||||
JMenu tools = new JMenu("Tools");
|
||||
JMenuItem identitiesItem = new JMenuItem("Identities…");
|
||||
JMenuItem identitiesItem = new JMenuItem("Identities…", Icons.of("IDENTITY_MANAGER"));
|
||||
identitiesItem.addActionListener(e -> showIdentities());
|
||||
JMenuItem options = new JMenuItem("Options…");
|
||||
JMenuItem options = new JMenuItem("Options…", Icons.of("SETTINGS"));
|
||||
options.addActionListener(e -> showSettings());
|
||||
tools.add(identitiesItem);
|
||||
tools.addSeparator();
|
||||
tools.add(options);
|
||||
|
||||
JMenu help = new JMenu("Help");
|
||||
JMenuItem about = new JMenuItem("About");
|
||||
JMenuItem about = new JMenuItem("About", Icons.of("ABOUT"));
|
||||
about.addActionListener(e -> showAbout());
|
||||
help.add(about);
|
||||
|
||||
@@ -208,14 +212,14 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
private void rebuildBookmarksMenu() {
|
||||
bookmarksMenu.removeAll();
|
||||
for (Bookmark b : bookmarks.all()) {
|
||||
JMenuItem item = new JMenuItem(b.displayName());
|
||||
JMenuItem item = new JMenuItem(b.displayName(), Icons.of("SERVER_GREEN"));
|
||||
item.addActionListener(e -> connectToBookmark(b));
|
||||
bookmarksMenu.add(item);
|
||||
}
|
||||
if (!bookmarks.all().isEmpty()) bookmarksMenu.addSeparator();
|
||||
JMenuItem addCurrent = new JMenuItem("Add current server…");
|
||||
JMenuItem addCurrent = new JMenuItem("Add current server…", Icons.of("BOOKMARK_ADD"));
|
||||
addCurrent.addActionListener(e -> addCurrentServerBookmark());
|
||||
JMenuItem manage = new JMenuItem("Manage bookmarks…");
|
||||
JMenuItem manage = new JMenuItem("Manage bookmarks…", Icons.of("BOOKMARK_MANAGER"));
|
||||
manage.addActionListener(e -> new BookmarksDialog(this, bookmarks, identities,
|
||||
this::connectToBookmark, this::rebuildBookmarksMenu).setVisible(true));
|
||||
bookmarksMenu.add(addCurrent);
|
||||
@@ -275,6 +279,19 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
return tb;
|
||||
}
|
||||
|
||||
/** Rebuilds the icon-bearing chrome after the active icon pack changed. */
|
||||
private void rebuildIcons() {
|
||||
setIconImage(Icons.app().getImage());
|
||||
setJMenuBar(buildMenuBar());
|
||||
remove(toolbar);
|
||||
toolbar = buildToolbar();
|
||||
add(toolbar, BorderLayout.NORTH);
|
||||
updateToolbar();
|
||||
refreshTabs();
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private JPanel buildStatusBar() {
|
||||
JPanel bar = new JPanel(new BorderLayout());
|
||||
bar.setBackground(Theme.STATUS_BG);
|
||||
@@ -574,9 +591,9 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
||||
boolean micMuted = connected && selected.isMicMuted();
|
||||
boolean deaf = connected && selected.isDeafened();
|
||||
micButton.setSelected(micMuted);
|
||||
micButton.setIcon(micMuted ? Icons.micMuted() : Icons.mic());
|
||||
micButton.setIcon(micMuted ? Icons.micMutedLarge() : Icons.mic());
|
||||
speakerButton.setSelected(deaf);
|
||||
speakerButton.setIcon(deaf ? Icons.speakerMuted() : Icons.speaker());
|
||||
speakerButton.setIcon(deaf ? Icons.speakerMutedLarge() : Icons.speaker());
|
||||
activeButton.setSelected(selected != null && selected == micTab);
|
||||
awayItem.setSelected(connected && selected.isAway());
|
||||
commanderItem.setSelected(connected && selected.isCommander());
|
||||
|
||||
Reference in New Issue
Block a user