Show servers' icons on bookmarks, and their host button in the toolbar's corner

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 22:28:35 +00:00
parent cf1db61a4a
commit 2c1b37ee30
20 changed files with 419 additions and 30 deletions

View File

@@ -0,0 +1,74 @@
package com.ts3client.ui;
import com.formdev.flatlaf.util.UIScale;
import com.ts3client.net.HostButton;
import com.ts3client.net.PictureDownloads;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.Image;
import java.io.File;
import java.util.Objects;
/**
* The server's host button in the toolbar's corner: its own picture, fitted to the
* toolbar's height, or TeamSpeak's host button icon while there is none (yet).
*/
final class HostButtonView extends JButton {
/** Keeps a banner-shaped picture from crowding out the rest of the toolbar. */
private static final int MAX_ASPECT = 6;
private final PictureDownloads pictures;
private final Runnable onPictureLoaded = () -> SwingUtilities.invokeLater(this::refreshIcon);
private HostButton shown;
HostButtonView(PictureDownloads pictures) {
this.pictures = pictures;
setVisible(false);
addActionListener(e -> {
if (shown != null && !shown.url().isEmpty()) Links.open(shown.url(), this);
});
}
/** @param button the selected server's, or {@code null} to hide it */
void show(HostButton button) {
if (Objects.equals(button, shown)) return;
shown = button;
setVisible(button != null);
if (button == null) return;
setToolTipText(!button.tooltip().isEmpty() ? button.tooltip() : button.url().isEmpty() ? null : button.url());
refreshIcon();
}
@Override
public void addNotify() {
super.addNotify();
pictures.addListener(onPictureLoaded);
}
@Override
public void removeNotify() {
pictures.removeListener(onPictureLoaded);
super.removeNotify();
}
private void refreshIcon() {
if (shown == null) return;
ImageIcon picture = shown.gfxUrl().isEmpty() ? null : picture(pictures.get(shown.gfxUrl()));
setIcon(picture != null ? picture : Icons.of("HOSTER_BUTTON", UIScale.scale(IconTheme.TOOLBAR_SIZE)));
}
private static ImageIcon picture(File file) {
if (file == null) return null;
ImageIcon icon = new ImageIcon(file.getPath());
int w = icon.getIconWidth();
int h = icon.getIconHeight();
if (w <= 0 || h <= 0) return null;
int height = UIScale.scale(IconTheme.TOOLBAR_SIZE);
int width = Math.min(Math.max(1, Math.round((float) w * height / h)), height * MAX_ASPECT);
if (w == width && h == height) return icon;
return new ImageIcon(icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH));
}
}