mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
Improve display of chat messages for app
This commit is contained in:
@@ -6,6 +6,7 @@ import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
@@ -15,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import forge.Singletons;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.model.FModel;
|
||||
import forge.net.ChatMessage;
|
||||
import forge.net.IOnlineChatInterface;
|
||||
import forge.net.IRemote;
|
||||
import forge.net.event.MessageEvent;
|
||||
@@ -132,7 +134,7 @@ public enum FNetOverlay implements IOnlineChatInterface {
|
||||
public void show() {
|
||||
show(null);
|
||||
}
|
||||
public void show(final String message) {
|
||||
public void show(final ChatMessage message) {
|
||||
if (!hasBeenShown) {
|
||||
hasBeenShown = true;
|
||||
loadLocation();
|
||||
@@ -144,7 +146,7 @@ public enum FNetOverlay implements IOnlineChatInterface {
|
||||
});
|
||||
}
|
||||
if (message != null) {
|
||||
txtLog.setText(message);
|
||||
txtLog.setText(message.getFormattedMessage());
|
||||
}
|
||||
window.setVisible(true);
|
||||
}
|
||||
@@ -203,7 +205,7 @@ public enum FNetOverlay implements IOnlineChatInterface {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMessage(final String message) {
|
||||
txtLog.append(message);
|
||||
public void addMessage(final ChatMessage message) {
|
||||
txtLog.append(message.getFormattedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.menus.IMenuProvider;
|
||||
import forge.menus.MenuUtil;
|
||||
import forge.net.ChatMessage;
|
||||
import forge.net.NetConnectUtil;
|
||||
import forge.screens.home.CHomeUI;
|
||||
import forge.screens.home.CLobby;
|
||||
@@ -55,7 +56,7 @@ public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider {
|
||||
}
|
||||
});
|
||||
|
||||
final String result = NetConnectUtil.host(VSubmenuOnlineLobby.SINGLETON_INSTANCE, FNetOverlay.SINGLETON_INSTANCE);
|
||||
final ChatMessage result = NetConnectUtil.host(VSubmenuOnlineLobby.SINGLETON_INSTANCE, FNetOverlay.SINGLETON_INSTANCE);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
@@ -79,7 +80,7 @@ public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider {
|
||||
}
|
||||
});
|
||||
|
||||
final String result = NetConnectUtil.join(url, VSubmenuOnlineLobby.SINGLETON_INSTANCE, FNetOverlay.SINGLETON_INSTANCE);
|
||||
final ChatMessage result = NetConnectUtil.join(url, VSubmenuOnlineLobby.SINGLETON_INSTANCE, FNetOverlay.SINGLETON_INSTANCE);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
package forge.screens.online;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
||||
|
||||
import forge.Graphics;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.assets.TextRenderer;
|
||||
import forge.assets.FSkinColor.Colors;
|
||||
import forge.model.FModel;
|
||||
import forge.net.ChatMessage;
|
||||
import forge.net.IOnlineChatInterface;
|
||||
import forge.net.IRemote;
|
||||
import forge.net.event.MessageEvent;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.FScreen;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.toolbox.FEvent;
|
||||
import forge.toolbox.FEvent.FEventHandler;
|
||||
import forge.toolbox.FChoiceList;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.toolbox.FTextField;
|
||||
import forge.util.Utils;
|
||||
|
||||
@@ -22,7 +28,7 @@ public class OnlineChatScreen extends FScreen implements IOnlineChatInterface {
|
||||
|
||||
private IRemote gameClient;
|
||||
private final ForgePreferences prefs = FModel.getPreferences();
|
||||
private final FChoiceList<String> lstLog = add(new FChoiceList<String>(new ArrayList<String>()));
|
||||
private final ChatLog lstLog = add(new ChatLog());
|
||||
private final FTextField txtSendMessage = add(new FTextField());
|
||||
|
||||
public OnlineChatScreen() {
|
||||
@@ -44,7 +50,11 @@ public class OnlineChatScreen extends FScreen implements IOnlineChatInterface {
|
||||
txtSendMessage.setText("");
|
||||
|
||||
if (gameClient != null) {
|
||||
gameClient.send(new MessageEvent(prefs.getPref(FPref.PLAYER_NAME), message));
|
||||
String source = prefs.getPref(FPref.PLAYER_NAME);
|
||||
if (lstLog.getChildCount() % 2 == 1) {
|
||||
source = "RemoteGuy"; //TODO: Remove this
|
||||
}
|
||||
gameClient.send(new MessageEvent(source, message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,9 +75,103 @@ public class OnlineChatScreen extends FScreen implements IOnlineChatInterface {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMessage(String message) {
|
||||
lstLog.addItem(message);
|
||||
lstLog.scrollToBottom();
|
||||
public void addMessage(ChatMessage message) {
|
||||
lstLog.addMessage(message);
|
||||
Gdx.graphics.requestRendering();
|
||||
}
|
||||
|
||||
private static class ChatLog extends FScrollPane {
|
||||
@Override
|
||||
protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) {
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
float inset = 6 * PADDING;
|
||||
float bubbleWidth = visibleWidth - inset;
|
||||
|
||||
for (FDisplayObject obj : getChildren()) {
|
||||
ChatMessageBubble bubble = (ChatMessageBubble)obj;
|
||||
if (bubble.isLocal) { //right-align local messages
|
||||
bubble.setBounds(x + inset, y, bubbleWidth, bubble.getPreferredHeight(bubbleWidth));
|
||||
}
|
||||
else {
|
||||
bubble.setBounds(x, y, bubbleWidth, bubble.getPreferredHeight(bubbleWidth));
|
||||
}
|
||||
y += bubble.getHeight() + PADDING;
|
||||
}
|
||||
return new ScrollBounds(visibleWidth, y - PADDING);
|
||||
}
|
||||
|
||||
private void addMessage(ChatMessage message) {
|
||||
add(new ChatMessageBubble(message));
|
||||
revalidate();
|
||||
scrollToBottom();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ChatMessageBubble extends FDisplayObject {
|
||||
private static final FSkinFont FONT = FSkinFont.get(12);
|
||||
private static final FSkinColor LOCAL_COLOR = FSkinColor.get(Colors.CLR_ZEBRA);
|
||||
private static final FSkinColor REMOTE_COLOR = LOCAL_COLOR.getContrastColor(-20);
|
||||
private static final FSkinColor MESSAGE_COLOR = FSkinColor.get(Colors.CLR_TEXT);
|
||||
private static final FSkinColor SOURCE_COLOR = MESSAGE_COLOR.alphaColor(0.75f);
|
||||
private static final FSkinColor TIMESTAMP_COLOR = MESSAGE_COLOR.alphaColor(0.5f);
|
||||
private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS);
|
||||
private static final float BORDER_THICKNESS = Utils.scale(1);
|
||||
private static final float TEXT_INSET = Utils.scale(5);
|
||||
private static final float TRIANGLE_WIDTH = Utils.scale(5);
|
||||
|
||||
private final ChatMessage message;
|
||||
private final boolean isLocal;
|
||||
private final String header;
|
||||
private final TextRenderer textRenderer = new TextRenderer();
|
||||
|
||||
private ChatMessageBubble(ChatMessage message0) {
|
||||
message = message0;
|
||||
isLocal = message.isLocal();
|
||||
if (isLocal || message.getSource() == null) {
|
||||
header = null;
|
||||
}
|
||||
else {
|
||||
header = message.getSource() + ":";
|
||||
}
|
||||
}
|
||||
|
||||
public float getPreferredHeight(float width) {
|
||||
float height = FONT.getCapHeight() + 4 * TEXT_INSET + TRIANGLE_WIDTH;
|
||||
if (header != null) {
|
||||
height += FONT.getLineHeight() + TEXT_INSET;
|
||||
}
|
||||
height += textRenderer.getWrappedBounds(message.getMessage(), FONT, width - 2 * TEXT_INSET).height;
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics g) {
|
||||
float x = isLocal ? 0 : TRIANGLE_WIDTH;
|
||||
float y = TEXT_INSET;
|
||||
float w = getWidth() - TRIANGLE_WIDTH;
|
||||
float h = getHeight() - TEXT_INSET;
|
||||
FSkinColor color = isLocal ? LOCAL_COLOR : REMOTE_COLOR;
|
||||
HAlignment horzAlignment = isLocal ? HAlignment.RIGHT : HAlignment.LEFT;
|
||||
|
||||
g.fillRect(color, x, y, w, h);
|
||||
g.drawRect(BORDER_THICKNESS, BORDER_COLOR, x, y, w, h);
|
||||
|
||||
x += TEXT_INSET;
|
||||
y += TEXT_INSET;
|
||||
w -= 2 * TEXT_INSET;
|
||||
|
||||
if (!isLocal && message.getSource() != null) {
|
||||
float sourceHeight = FONT.getLineHeight();
|
||||
g.drawText(message.getSource() + ":", FONT, SOURCE_COLOR, x, y, w, sourceHeight, false, horzAlignment, true);
|
||||
y += sourceHeight + TEXT_INSET;
|
||||
}
|
||||
|
||||
float timestampHeight = FONT.getCapHeight();
|
||||
g.drawText(message.getTimestamp(), FONT, TIMESTAMP_COLOR, x, h - timestampHeight, w, timestampHeight, false, horzAlignment, true);
|
||||
|
||||
h -= y + timestampHeight + TEXT_INSET;
|
||||
textRenderer.drawText(g, message.getMessage(), FONT, MESSAGE_COLOR, x, y, w, h, y, h, true, horzAlignment, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import forge.FThreads;
|
||||
import forge.Forge;
|
||||
import forge.interfaces.ILobbyView;
|
||||
import forge.match.GameLobby;
|
||||
import forge.net.ChatMessage;
|
||||
import forge.net.IOnlineChatInterface;
|
||||
import forge.net.IOnlineLobby;
|
||||
import forge.net.NetConnectUtil;
|
||||
@@ -51,7 +52,7 @@ public class OnlineLobbyScreen extends LobbyScreen implements IOnlineLobby {
|
||||
LoadingOverlay.show(caption, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String result;
|
||||
final ChatMessage result;
|
||||
final IOnlineChatInterface chatInterface = (IOnlineChatInterface)OnlineScreen.Chat.getScreen();
|
||||
if (joinServer) {
|
||||
result = NetConnectUtil.join(url, OnlineLobbyScreen.this, chatInterface);
|
||||
|
||||
@@ -2,5 +2,5 @@ package forge.net;
|
||||
|
||||
public interface IOnlineChatInterface {
|
||||
void setGameClient(IRemote iRemote);
|
||||
void addMessage(String message);
|
||||
void addMessage(ChatMessage message);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package forge.net;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.GuiBase;
|
||||
@@ -41,7 +38,7 @@ public class NetConnectUtil {
|
||||
return url;
|
||||
}
|
||||
|
||||
public static String host(final IOnlineLobby onlineLobby, final IOnlineChatInterface chatInterface) {
|
||||
public static ChatMessage host(final IOnlineLobby onlineLobby, final IOnlineChatInterface chatInterface) {
|
||||
final int port = ForgeProfileProperties.getServerPort();
|
||||
final FServerManager server = FServerManager.getInstance();
|
||||
final ServerGameLobby lobby = new ServerGameLobby();
|
||||
@@ -72,7 +69,7 @@ public class NetConnectUtil {
|
||||
}
|
||||
@Override
|
||||
public final void message(final String source, final String message) {
|
||||
chatInterface.addMessage(formatMessage(source, message));
|
||||
chatInterface.addMessage(new ChatMessage(source, message));
|
||||
}
|
||||
@Override
|
||||
public final void close() {
|
||||
@@ -84,7 +81,7 @@ public class NetConnectUtil {
|
||||
public final void send(final NetEvent event) {
|
||||
if (event instanceof MessageEvent) {
|
||||
final MessageEvent message = (MessageEvent) event;
|
||||
chatInterface.addMessage(formatMessage(message.getSource(), message.getMessage()));
|
||||
chatInterface.addMessage(new ChatMessage(message.getSource(), message.getMessage()));
|
||||
server.broadcast(event);
|
||||
}
|
||||
}
|
||||
@@ -97,7 +94,7 @@ public class NetConnectUtil {
|
||||
|
||||
view.update(true);
|
||||
|
||||
return String.format("Hosting on port %d.", port);
|
||||
return new ChatMessage(null, String.format("Hosting on port %d.", port));
|
||||
}
|
||||
|
||||
public static void copyHostedServerUrl() {
|
||||
@@ -107,7 +104,7 @@ public class NetConnectUtil {
|
||||
SOptionPane.showMessageDialog("Share the following URL with anyone who wishes to join your server. It has been copied to your clipboard for convenience.\n\n" + url, "Server URL", SOptionPane.INFORMATION_ICON);
|
||||
}
|
||||
|
||||
public static String join(final String url, final IOnlineLobby onlineLobby, final IOnlineChatInterface chatInterface) {
|
||||
public static ChatMessage join(final String url, final IOnlineLobby onlineLobby, final IOnlineChatInterface chatInterface) {
|
||||
final IGuiGame gui = GuiBase.getInterface().getNewGuiGame();
|
||||
final FGameClient client = new FGameClient(FModel.getPreferences().getPref(FPref.PLAYER_NAME), "0", gui);
|
||||
onlineLobby.setClient(client);
|
||||
@@ -118,7 +115,7 @@ public class NetConnectUtil {
|
||||
client.addLobbyListener(new ILobbyListener() {
|
||||
@Override
|
||||
public final void message(final String source, final String message) {
|
||||
chatInterface.addMessage(formatMessage(source, message));
|
||||
chatInterface.addMessage(new ChatMessage(source, message));
|
||||
}
|
||||
@Override
|
||||
public final void update(final GameLobbyData state, final int slot) {
|
||||
@@ -154,20 +151,6 @@ public class NetConnectUtil {
|
||||
|
||||
client.connect(hostname, port);
|
||||
|
||||
return String.format("Connected to %s:%d", hostname, port);
|
||||
}
|
||||
|
||||
private final static SimpleDateFormat inFormat = new SimpleDateFormat("HH:mm:ss");
|
||||
|
||||
public static String formatMessage(final String source, final String message) {
|
||||
final String now = inFormat.format(new Date());
|
||||
final String toAdd;
|
||||
if (source == null) {
|
||||
toAdd = String.format("%n[%s] %s", now, message);
|
||||
}
|
||||
else {
|
||||
toAdd = String.format("%n[%s] %s: %s", now, source, message);
|
||||
}
|
||||
return toAdd;
|
||||
return new ChatMessage(null, String.format("Connected to %s:%d", hostname, port));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user