package com.ts3client.ui; import com.ts3client.config.Settings; import com.ts3client.gfx.IconPack; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.SwingConstants; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.File; /** * Options page for icon packs: which pack the user interface is drawn with, where * to look for more of them, and a viewer showing everything the pack contains. * *

Picking a pack applies it right away so the change can be seen in the window * behind the dialog; cancelling puts the previous one back. */ final class IconPackPanel extends JPanel { /** Size of the tiles in the icon viewer. */ private static final int PREVIEW_SIZE = 32; private static final int TILE = 44; /** Stands for "no pack": the icons the client draws itself. */ private static final String BUILT_IN = "Built-in icons"; private final Settings settings; private final String originalPackId; private final String originalPackDir; private final JComboBox packCombo = new JComboBox<>(); private final JLabel packInfo = new JLabel(); private final JTextField packDirField; private final DefaultListModel previewModel = new DefaultListModel<>(); private final JList preview = new JList<>(previewModel); IconPackPanel(Settings settings) { super(new BorderLayout(0, 8)); this.settings = settings; this.originalPackId = settings.iconPack; this.originalPackDir = settings.iconPackDir; this.packDirField = new JTextField(settings.iconPackDir, 18); setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12)); add(buildHeader(), BorderLayout.NORTH); add(buildPreview(), BorderLayout.CENTER); reloadPacks(); } /** Copies the chosen pack into the settings; the caller saves them. */ void apply() { settings.iconPackDir = packDirField.getText().trim(); Object selected = packCombo.getSelectedItem(); settings.iconPack = selected instanceof IconPack pack ? pack.id() : ""; } /** Puts back the pack the dialog started with, for a cancelled edit. */ void revert() { settings.iconPack = originalPackId; settings.iconPackDir = originalPackDir; IconTheme.get().reload(settings); } // ---- layout ---- private JComponent buildHeader() { JPanel p = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(2, 2, 2, 2); c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; packCombo.setToolTipText("Icon packs installed here or in a TeamSpeak 3 client"); packCombo.addActionListener(e -> onPackSelected()); packCombo.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean focus) { super.getListCellRendererComponent(list, value, index, selected, focus); setText(value instanceof IconPack pack ? pack.name() : String.valueOf(value)); return this; } }); int row = 0; addRow(p, c, row++, new JLabel("Icon pack:"), packCombo); c.gridx = 1; c.gridy = row++; packInfo.setEnabled(false); p.add(packInfo, c); JPanel dirRow = new JPanel(new BorderLayout(6, 0)); JButton browse = new JButton("Browse…"); browse.addActionListener(e -> browseForPackFolder()); dirRow.add(packDirField, BorderLayout.CENTER); dirRow.add(browse, BorderLayout.EAST); packDirField.setToolTipText("Extra folder to look for icon packs in"); addRow(p, c, row, new JLabel("Extra pack folder:"), dirRow); return p; } private JComponent buildPreview() { preview.setLayoutOrientation(JList.HORIZONTAL_WRAP); preview.setVisibleRowCount(-1); preview.setFixedCellWidth(TILE); preview.setFixedCellHeight(TILE); preview.setCellRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean focus) { super.getListCellRendererComponent(list, value, index, selected, focus); String key = String.valueOf(value); ImageIcon icon = Icons.of(key, PREVIEW_SIZE); setText(""); setIcon(icon); setToolTipText(key); setHorizontalAlignment(SwingConstants.CENTER); return this; } }); JScrollPane scroll = new JScrollPane(preview); scroll.setPreferredSize(new Dimension(360, 200)); scroll.setBorder(BorderFactory.createTitledBorder("Icons in this pack")); return scroll; } // ---- behaviour ---- private void reloadPacks() { IconTheme theme = IconTheme.get(); theme.reload(settings); // Filling the combo box changes its selection, and with it the active pack, // so remember the one the settings asked for before touching it. IconPack selected = theme.activePack(); packCombo.removeAllItems(); packCombo.addItem(BUILT_IN); for (IconPack pack : theme.packs()) packCombo.addItem(pack); packCombo.setSelectedItem(selected == null ? BUILT_IN : selected); onPackSelected(); } private void onPackSelected() { Object selected = packCombo.getSelectedItem(); IconPack pack = selected instanceof IconPack p ? p : null; IconTheme.get().setPack(pack); previewModel.clear(); if (pack == null) { packInfo.setText("Drawn by the client itself"); } else { for (String key : pack.keys()) previewModel.addElement(key); packInfo.setText(pack.keys().size() + " icons" + (pack.fallsBack() ? ", missing ones from the default pack" : "")); } } private void browseForPackFolder() { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setDialogTitle("Folder containing icon packs"); String current = packDirField.getText().trim(); if (!current.isEmpty()) chooser.setCurrentDirectory(new File(current)); if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return; packDirField.setText(chooser.getSelectedFile().getAbsolutePath()); settings.iconPackDir = packDirField.getText(); reloadPacks(); } private static void addRow(JPanel p, GridBagConstraints c, int row, JLabel label, Component field) { c.gridx = 0; c.gridy = row; c.weightx = 0; p.add(label, c); c.gridx = 1; c.weightx = 1; p.add(field, c); } }