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);
}
}