Improve display of chat messages for app

This commit is contained in:
drdev
2015-06-06 18:11:36 +00:00
parent fc0e527877
commit 7a2bac60de
6 changed files with 131 additions and 40 deletions

View File

@@ -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());
}
}

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -2,5 +2,5 @@ package forge.net;
public interface IOnlineChatInterface {
void setGameClient(IRemote iRemote);
void addMessage(String message);
void addMessage(ChatMessage message);
}

View File

@@ -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));
}
}