Paint the client with FlatLaf, in a light and a dark theme
The look-and-feel is FlatLaf now, chosen light or dark on the new Design tab and remembered in the settings. Theme keeps only the colours TeamSpeak gives meaning to (talking, away, muted, channel and server names) and takes its surfaces and fonts from the look-and-feel, so a switch recolours the whole window, chat logs included: the HTML panes share one themed stylesheet and re-parse their content when the theme changes. Also fixes the channel tree not scrolling: the tree listened for the mouse wheel to re-check its hover row, and AWT only forwards a wheel event to the enclosing scroll pane when the component under the pointer has no wheel listener of its own. The hover row now follows the viewport instead, which also covers scrollbar drags and keyboard scrolling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -121,7 +121,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
public static ImageIcon clientIdle(int size) {
|
||||
return themed("PLAYER_OFF", size, g -> paintPerson(g, Theme.IDLE_CLIENT));
|
||||
return themed("PLAYER_OFF", size, g -> paintPerson(g, Theme.idleClient()));
|
||||
}
|
||||
|
||||
public static ImageIcon clientTalking() {
|
||||
@@ -129,7 +129,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
public static ImageIcon clientTalking(int size) {
|
||||
return themed("PLAYER_ON", size, g -> paintPerson(g, Theme.TALKING));
|
||||
return themed("PLAYER_ON", size, g -> paintPerson(g, Theme.talking()));
|
||||
}
|
||||
|
||||
public static ImageIcon clientAway() {
|
||||
@@ -137,7 +137,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
public static ImageIcon clientAway(int size) {
|
||||
return themed("AWAY", size, g -> paintPerson(g, Theme.AWAY));
|
||||
return themed("AWAY", size, g -> paintPerson(g, Theme.away()));
|
||||
}
|
||||
|
||||
/** A channel commander that is not talking. */
|
||||
@@ -151,7 +151,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
public static ImageIcon clientQuery() {
|
||||
return themed("SERVER_QUERY", g -> paintPerson(g, Theme.IDLE_CLIENT));
|
||||
return themed("SERVER_QUERY", g -> paintPerson(g, Theme.idleClient()));
|
||||
}
|
||||
|
||||
public static ImageIcon micMuted() {
|
||||
@@ -199,12 +199,12 @@ public final class Icons {
|
||||
|
||||
/** A channel commander that is not talking. */
|
||||
public static ImageIcon clientCommander(int size) {
|
||||
return themed("PLAYER_COMMANDER_OFF", size, g -> paintPerson(g, Theme.IDLE_CLIENT));
|
||||
return themed("PLAYER_COMMANDER_OFF", size, g -> paintPerson(g, Theme.idleClient()));
|
||||
}
|
||||
|
||||
/** A channel commander that is talking. */
|
||||
public static ImageIcon clientCommanderTalking(int size) {
|
||||
return themed("PLAYER_COMMANDER_ON", size, g -> paintPerson(g, Theme.TALKING));
|
||||
return themed("PLAYER_COMMANDER_ON", size, g -> paintPerson(g, Theme.talking()));
|
||||
}
|
||||
|
||||
// ---- toolbar / action icons ----
|
||||
@@ -257,8 +257,8 @@ public final class Icons {
|
||||
Graphics2D g = img.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g.drawImage(channel.getImage(), 0, (height - channel.getIconHeight()) / 2, null);
|
||||
g.setColor(Theme.IDLE_CLIENT);
|
||||
g.setFont(Theme.UI_FONT);
|
||||
g.setColor(Theme.idleClient());
|
||||
g.setFont(Theme.uiFont());
|
||||
java.awt.FontMetrics fm = g.getFontMetrics();
|
||||
int slashX = channel.getIconWidth() + (gap - fm.stringWidth("/")) / 2;
|
||||
g.drawString("/", slashX, (height + fm.getAscent()) / 2 - 1);
|
||||
@@ -270,7 +270,7 @@ public final class Icons {
|
||||
|
||||
/** The toolbar's away marker. */
|
||||
public static ImageIcon away() {
|
||||
return themed("AWAY", IconTheme.TOOLBAR_SIZE, g -> paintPerson(g, Theme.AWAY));
|
||||
return themed("AWAY", IconTheme.TOOLBAR_SIZE, g -> paintPerson(g, Theme.away()));
|
||||
}
|
||||
|
||||
public static ImageIcon settings() {
|
||||
@@ -329,7 +329,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
private static void paintMicMuted(Graphics2D g) {
|
||||
g.setColor(Theme.MUTED);
|
||||
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);
|
||||
@@ -339,7 +339,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
private static void paintSpeakerMuted(Graphics2D g) {
|
||||
g.setColor(Theme.MUTED);
|
||||
g.setColor(Theme.muted());
|
||||
g.fillRect(2, 6, 3, 4);
|
||||
int[] xs = {5, 9, 9, 5};
|
||||
int[] ys = {6, 3, 13, 10};
|
||||
@@ -350,7 +350,7 @@ public final class Icons {
|
||||
|
||||
/** Same shape as {@link #paintMicMuted}, but grey: unavailable, not muted by choice. */
|
||||
private static void paintMicDisabled(Graphics2D g) {
|
||||
g.setColor(Theme.IDLE_CLIENT);
|
||||
g.setColor(Theme.idleClient());
|
||||
g.fillRoundRect(6, 2, 4, 7, 2, 2);
|
||||
g.setStroke(new BasicStroke(1.4f));
|
||||
g.drawArc(4, 6, 8, 6, 200, 140);
|
||||
@@ -361,7 +361,7 @@ public final class Icons {
|
||||
|
||||
/** Same shape as {@link #paintSpeakerMuted}, but grey: unavailable, not muted by choice. */
|
||||
private static void paintSpeakerDisabled(Graphics2D g) {
|
||||
g.setColor(Theme.IDLE_CLIENT);
|
||||
g.setColor(Theme.idleClient());
|
||||
g.fillRect(2, 6, 3, 4);
|
||||
int[] xs = {5, 9, 9, 5};
|
||||
int[] ys = {6, 3, 13, 10};
|
||||
@@ -373,7 +373,7 @@ public final class Icons {
|
||||
/** {@link #paintMicMuted}, marked with a small dot: silenced, but not reported as muted. */
|
||||
private static void paintMicLocalMuted(Graphics2D g) {
|
||||
paintMicMuted(g);
|
||||
g.setColor(Theme.ACCENT);
|
||||
g.setColor(Theme.accent());
|
||||
g.fillOval(11, 10, 4, 4);
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
private static void paintDisconnect(Graphics2D g) {
|
||||
g.setColor(Theme.MUTED);
|
||||
g.setColor(Theme.muted());
|
||||
g.setStroke(new BasicStroke(2f));
|
||||
g.drawLine(3, 8, 8, 8);
|
||||
g.fillRoundRect(8, 5, 5, 6, 2, 2);
|
||||
@@ -414,7 +414,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
private static void paintMicActive(Graphics2D g) {
|
||||
g.setColor(Theme.TALKING);
|
||||
g.setColor(Theme.talking());
|
||||
g.fillOval(1, 1, 14, 14);
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRoundRect(6, 3, 4, 6, 2, 2);
|
||||
@@ -450,7 +450,7 @@ public final class Icons {
|
||||
}
|
||||
|
||||
private static void paintApp(Graphics2D g) {
|
||||
g.setColor(Theme.ACCENT);
|
||||
g.setColor(Theme.accent());
|
||||
g.fillRoundRect(1, 1, 14, 14, 4, 4);
|
||||
g.setColor(Color.WHITE);
|
||||
g.setStroke(new BasicStroke(1.6f));
|
||||
|
||||
Reference in New Issue
Block a user