GUI Improvements

This commit is contained in:
William Blake Galbreath
2025-01-12 17:34:29 -08:00
committed by granny
parent c5617e1e66
commit 7e8af548ea
7 changed files with 392 additions and 421 deletions

View File

@@ -0,0 +1,58 @@
package org.purpurmc.purpur.gui;
import net.md_5.bungee.api.ChatColor;
import java.awt.Color;
import java.util.HashMap;
import java.util.Map;
public enum GUIColor {
BLACK(ChatColor.BLACK, new Color(0x000000)),
DARK_BLUE(ChatColor.DARK_BLUE, new Color(0x0000AA)),
DARK_GREEN(ChatColor.DARK_GREEN, new Color(0x00AA00)),
DARK_AQUA(ChatColor.DARK_AQUA, new Color(0x009999)),
DARK_RED(ChatColor.DARK_RED, new Color(0xAA0000)),
DARK_PURPLE(ChatColor.DARK_PURPLE, new Color(0xAA00AA)),
GOLD(ChatColor.GOLD, new Color(0xBB8800)),
GRAY(ChatColor.GRAY, new Color(0x888888)),
DARK_GRAY(ChatColor.DARK_GRAY, new Color(0x444444)),
BLUE(ChatColor.BLUE, new Color(0x5555FF)),
GREEN(ChatColor.GREEN, new Color(0x55FF55)),
AQUA(ChatColor.AQUA, new Color(0x55DDDD)),
RED(ChatColor.RED, new Color(0xFF5555)),
LIGHT_PURPLE(ChatColor.LIGHT_PURPLE, new Color(0xFF55FF)),
YELLOW(ChatColor.YELLOW, new Color(0xFFBB00)),
WHITE(ChatColor.WHITE, new Color(0xBBBBBB));
private final ChatColor chat;
private final Color color;
private static final Map<ChatColor, GUIColor> BY_CHAT = new HashMap<>();
GUIColor(ChatColor chat, Color color) {
this.chat = chat;
this.color = color;
}
public Color getColor() {
return color;
}
public ChatColor getChatColor() {
return chat;
}
public String getCode() {
return chat.toString();
}
public static GUIColor getColor(ChatColor chat) {
return BY_CHAT.get(chat);
}
static {
for (GUIColor color : values()) {
BY_CHAT.put(color.chat, color);
}
}
}

View File

@@ -0,0 +1,83 @@
package org.purpurmc.purpur.gui;
import com.google.common.collect.Sets;
import javax.swing.UIManager;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import javax.swing.JTextPane;
import javax.swing.Timer;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import java.util.Set;
public class JColorTextPane extends JTextPane {
private static final GUIColor DEFAULT_COLOR;
static {
DEFAULT_COLOR = UIManager.getSystemLookAndFeelClassName().equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel")
? GUIColor.WHITE : GUIColor.BLACK;
}
public void append(String msg) {
// TODO: update to use adventure instead
BaseComponent[] components = TextComponent.fromLegacyText(DEFAULT_COLOR.getCode() + msg, DEFAULT_COLOR.getChatColor());
for (BaseComponent component : components) {
String text = component.toPlainText();
if (text == null || text.isEmpty()) {
continue;
}
GUIColor guiColor = GUIColor.getColor(component.getColor());
StyleContext context = StyleContext.getDefaultStyleContext();
AttributeSet attr = context.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, guiColor.getColor());
attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Bold, component.isBold() || guiColor != DEFAULT_COLOR);
attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Italic, component.isItalic());
attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Underline, component.isUnderlined());
attr = context.addAttribute(attr, StyleConstants.CharacterConstants.StrikeThrough, component.isStrikethrough());
//attr = context.addAttribute(attr, StyleConstants.CharacterConstants.Blink, component.isObfuscated()); // no such thing as Blink, sadly
try {
int pos = getDocument().getLength();
getDocument().insertString(pos, text, attr);
if (component.isObfuscated()) {
// dirty hack to blink some text
Blink blink = new Blink(pos, text.length(), attr, context.addAttribute(attr, StyleConstants.Foreground, getBackground()));
BLINKS.add(blink);
}
} catch (BadLocationException ignore) {
}
}
}
private static final Set<Blink> BLINKS = Sets.newHashSet();
private static boolean SYNC_BLINK;
static {
new Timer(500, e -> {
SYNC_BLINK = !SYNC_BLINK;
BLINKS.forEach(Blink::blink);
}).start();
}
public class Blink {
private final int start, length;
private final AttributeSet attr1, attr2;
private Blink(int start, int length, AttributeSet attr1, AttributeSet attr2) {
this.start = start;
this.length = length;
this.attr1 = attr1;
this.attr2 = attr2;
}
private void blink() {
getStyledDocument().setCharacterAttributes(start, length, SYNC_BLINK ? attr1 : attr2, true);
}
}
}