Initial commit: TS3J TeamSpeak 3 Java client
Swing desktop client (core/desktop/swing Maven modules) built on the ts3j protocol library, included as a submodule. Native Opus voice with voice-activation detection, push-to-talk, and audio pre-processing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
196
ts3-client/swing/src/main/java/com/ts3client/ui/Icons.java
Normal file
196
ts3-client/swing/src/main/java/com/ts3client/ui/Icons.java
Normal file
@@ -0,0 +1,196 @@
|
||||
package com.ts3client.ui;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* Programmatically drawn vector icons (no external image assets), so the client
|
||||
* is fully self-contained. All icons are rendered at 16×16 with a small
|
||||
* cache.
|
||||
*/
|
||||
public final class Icons {
|
||||
|
||||
private static final int SZ = 16;
|
||||
|
||||
private Icons() {
|
||||
}
|
||||
|
||||
private interface Painter {
|
||||
void paint(Graphics2D g);
|
||||
}
|
||||
|
||||
private static ImageIcon make(Painter p) {
|
||||
BufferedImage img = new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = img.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
p.paint(g);
|
||||
g.dispose();
|
||||
return new ImageIcon(img);
|
||||
}
|
||||
|
||||
// ---- tree icons ----
|
||||
|
||||
public static ImageIcon server() {
|
||||
return make(g -> {
|
||||
g.setColor(new Color(0x2C6EA5));
|
||||
g.fillRoundRect(2, 3, 12, 4, 2, 2);
|
||||
g.fillRoundRect(2, 9, 12, 4, 2, 2);
|
||||
g.setColor(new Color(0x9FD0F0));
|
||||
g.fillOval(4, 4, 2, 2);
|
||||
g.fillOval(4, 10, 2, 2);
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon channel() {
|
||||
return channelPainted(new Color(0x3E7CB1), false);
|
||||
}
|
||||
|
||||
public static ImageIcon channelLocked() {
|
||||
return channelPainted(new Color(0x8A6D3B), true);
|
||||
}
|
||||
|
||||
private static ImageIcon channelPainted(Color c, boolean lock) {
|
||||
return make(g -> {
|
||||
g.setColor(c);
|
||||
g.setStroke(new BasicStroke(1.6f));
|
||||
// simple speaker-cone glyph
|
||||
g.fillRect(2, 6, 3, 4);
|
||||
int[] xs = {5, 9, 9, 5};
|
||||
int[] ys = {6, 3, 13, 10};
|
||||
g.fillPolygon(xs, ys, 4);
|
||||
g.setStroke(new BasicStroke(1.4f));
|
||||
g.drawArc(9, 5, 4, 6, -60, 120);
|
||||
if (lock) {
|
||||
g.setColor(new Color(0xB8860B));
|
||||
g.fillRoundRect(10, 9, 5, 5, 1, 1);
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(12, 10, 1, 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ---- client status icons ----
|
||||
|
||||
public static ImageIcon clientIdle() {
|
||||
return person(Theme.IDLE_CLIENT);
|
||||
}
|
||||
|
||||
public static ImageIcon clientTalking() {
|
||||
return person(Theme.TALKING);
|
||||
}
|
||||
|
||||
public static ImageIcon clientAway() {
|
||||
return person(Theme.AWAY);
|
||||
}
|
||||
|
||||
private static ImageIcon person(Color c) {
|
||||
return make(g -> {
|
||||
g.setColor(c);
|
||||
g.fillOval(5, 2, 6, 6); // head
|
||||
g.fillRoundRect(3, 9, 10, 6, 4, 4); // shoulders
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon micMuted() {
|
||||
return make(g -> {
|
||||
g.setColor(Theme.MUTED);
|
||||
g.fillRoundRect(6, 2, 4, 7, 2, 2);
|
||||
g.setStroke(new BasicStroke(1.4f));
|
||||
g.drawArc(4, 6, 8, 6, 200, 140);
|
||||
g.drawLine(8, 12, 8, 14);
|
||||
g.setStroke(new BasicStroke(2f));
|
||||
g.drawLine(2, 2, 14, 14); // slash
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon speakerMuted() {
|
||||
return make(g -> {
|
||||
g.setColor(Theme.MUTED);
|
||||
g.fillRect(2, 6, 3, 4);
|
||||
int[] xs = {5, 9, 9, 5};
|
||||
int[] ys = {6, 3, 13, 10};
|
||||
g.fillPolygon(xs, ys, 4);
|
||||
g.setStroke(new BasicStroke(2f));
|
||||
g.drawLine(2, 2, 14, 14);
|
||||
});
|
||||
}
|
||||
|
||||
// ---- toolbar / action icons ----
|
||||
|
||||
public static ImageIcon connect() {
|
||||
return make(g -> {
|
||||
g.setColor(new Color(0x2E8B57));
|
||||
g.setStroke(new BasicStroke(2f));
|
||||
g.drawLine(3, 8, 8, 8);
|
||||
g.fillRoundRect(8, 5, 5, 6, 2, 2);
|
||||
g.drawLine(10, 3, 10, 5);
|
||||
g.drawLine(12, 3, 12, 5);
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon disconnect() {
|
||||
return make(g -> {
|
||||
g.setColor(Theme.MUTED);
|
||||
g.setStroke(new BasicStroke(2f));
|
||||
g.drawLine(3, 8, 8, 8);
|
||||
g.fillRoundRect(8, 5, 5, 6, 2, 2);
|
||||
g.drawLine(2, 3, 6, 13);
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon mic() {
|
||||
return make(g -> {
|
||||
g.setColor(new Color(0x37474F));
|
||||
g.fillRoundRect(6, 2, 4, 7, 2, 2);
|
||||
g.setStroke(new BasicStroke(1.4f));
|
||||
g.drawArc(4, 6, 8, 6, 200, 140);
|
||||
g.drawLine(8, 12, 8, 14);
|
||||
g.drawLine(6, 14, 10, 14);
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon speaker() {
|
||||
return make(g -> {
|
||||
g.setColor(new Color(0x37474F));
|
||||
g.fillRect(2, 6, 3, 4);
|
||||
int[] xs = {5, 9, 9, 5};
|
||||
int[] ys = {6, 3, 13, 10};
|
||||
g.fillPolygon(xs, ys, 4);
|
||||
g.setStroke(new BasicStroke(1.4f));
|
||||
g.drawArc(9, 5, 4, 6, -60, 120);
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon settings() {
|
||||
return make(g -> {
|
||||
g.setColor(new Color(0x37474F));
|
||||
g.setStroke(new BasicStroke(2f));
|
||||
g.drawOval(5, 5, 6, 6);
|
||||
for (int a = 0; a < 360; a += 45) {
|
||||
double r = Math.toRadians(a);
|
||||
int x1 = (int) (8 + Math.cos(r) * 5);
|
||||
int y1 = (int) (8 + Math.sin(r) * 5);
|
||||
int x2 = (int) (8 + Math.cos(r) * 7);
|
||||
int y2 = (int) (8 + Math.sin(r) * 7);
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static ImageIcon app() {
|
||||
return make(g -> {
|
||||
g.setColor(Theme.ACCENT);
|
||||
g.fillRoundRect(1, 1, 14, 14, 4, 4);
|
||||
g.setColor(Color.WHITE);
|
||||
g.setStroke(new BasicStroke(1.6f));
|
||||
g.drawArc(4, 5, 8, 8, 30, 120);
|
||||
g.drawArc(2, 3, 12, 12, 30, 120);
|
||||
g.fillOval(7, 9, 2, 2);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user