make chat into its own component

This commit is contained in:
RandomityGuy 2024-06-13 01:00:30 +05:30
parent 8a7ccc1c86
commit d94c09ad32
4 changed files with 200 additions and 152 deletions

164
src/gui/ChatCtrl.hx Normal file
View file

@ -0,0 +1,164 @@
package gui;
import gui.GuiControl.MouseState;
import src.Settings;
import hxd.res.BitmapFont;
import hxd.Key;
import h3d.Vector;
import src.ResourceLoader;
import net.NetCommands;
import net.Net;
@:publicFields
@:structInit
class ChatMessage {
var text:String;
var age:Float;
}
class ChatCtrl extends GuiControl {
var chatHud:GuiMLText;
var chatHudBg:GuiMLText;
var chatHudInput:GuiTextInput;
var chatInputBg:GuiImage;
var chatInputBgText:GuiText;
var chats:Array<ChatMessage>;
var chatFocused:Bool = false;
public function new() {
super();
var arial14fontdata = ResourceLoader.getFileEntry("data/font/Arial Bold.fnt");
var arial14b = new BitmapFont(arial14fontdata.entry);
@:privateAccess arial14b.loader = ResourceLoader.loader;
var arial14 = arial14b.toSdfFont(cast 15 * Settings.uiScale, MultiChannel);
this.chats = [];
this.chatHudBg = new GuiMLText(arial14, (s) -> arial14);
this.chatHudBg.position = new Vector(1, 21);
this.chatHudBg.extent = new Vector(200, 250);
this.chatHudBg.text.textColor = 0;
this.addChild(chatHudBg);
this.chatHud = new GuiMLText(arial14, (s) -> arial14);
this.chatHud.position = new Vector(0, 20);
this.chatHud.extent = new Vector(200, 250);
this.addChild(chatHud);
this.chatInputBg = new GuiImage(ResourceLoader.getResource('data/ui/xbox/fade_black.png', ResourceLoader.getImage, this.imageResources).toTile());
this.chatInputBg.position = new Vector(0, 0);
this.chatInputBg.extent = new Vector(200, 20);
this.addChild(chatInputBg);
this.chatInputBgText = new GuiText(arial14);
this.chatInputBgText.position = new Vector(0, 0);
this.chatInputBgText.extent = new Vector(200, 20);
this.chatInputBg.addChild(chatInputBgText);
this.chatInputBgText.text.textColor = 0xF29515;
this.chatInputBgText.text.text = "Chat:";
this.chatHudInput = new GuiTextInput(arial14);
this.chatHudInput.position = new Vector(40, 0);
this.chatHudInput.extent = new Vector(160, 20);
@:privateAccess this.chatHudInput.text.interactive.forceAnywherefocus = true;
this.addChild(chatHudInput);
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
var sendText = "";
this.chatHudInput.text.onFocus = (e) -> {
this.chatInputBgText.text.visible = true;
this.chatInputBg.bmp.visible = true;
chatFocused = true;
}
this.chatHudInput.text.onFocusLost = (e) -> {
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
sendText = "";
chatFocused = false;
}
this.chatHudInput.text.onKeyDown = (e) -> {
if (e.keyCode == Key.ENTER) {
if (StringTools.trim(this.chatHudInput.text.text) != "") {
sendText = '<font color="#F29515">${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}:</font> ${StringTools.htmlEscape(this.chatHudInput.text.text.substr(0, 50))}';
if (Net.isClient) {
NetCommands.sendChatMessage(StringTools.htmlEscape(sendText));
}
if (Net.isHost) {
NetCommands.sendServerChatMessage(StringTools.htmlEscape(sendText));
}
}
this.chatHudInput.text.text = "";
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
chatFocused = false;
}
if (e.keyCode == Key.ESCAPE) {
this.chatHudInput.text.text = "";
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
chatFocused = false;
@:privateAccess Key.keyPressed[Key.ESCAPE] = 0; // consume escape
}
@:privateAccess Key.keyPressed[e.keyCode] = 0; // consume keys
}
this.chatHud.text.text = "";
}
public inline function isChatFocused() {
return chatFocused;
}
public function addChatMessage(text:String) {
var realText = StringTools.htmlUnescape(text);
this.chats.push({
text: realText,
age: 10.0
});
if (this.chats.length > 10) {
this.chats = this.chats.slice(this.chats.length - 10);
}
redrawChatMessages();
}
function redrawChatMessages() {
var joined = this.chats.map(x -> x.text).join("<br/>");
this.chatHud.text.text = joined;
this.chatHudBg.text.text = StringTools.replace(joined, '#F29515', '#000000');
}
function tickChats(dt:Float) {
var needsRedraw = false;
var chatsToRemove = [];
for (chat in this.chats) {
chat.age -= dt;
if (chat.age < 0) {
chatsToRemove.push(chat);
}
}
while (chatsToRemove.length > 0) {
this.chats.remove(chatsToRemove[0]);
needsRedraw = true;
chatsToRemove.shift();
}
if (needsRedraw) {
redrawChatMessages();
}
}
public function updateChat(dt:Float) {
if (!chatFocused) {
if (Key.isPressed(Settings.controlsSettings.chat)) {
this.chatHudInput.text.focus();
}
}
tickChats(dt);
}
}

View file

@ -27,6 +27,7 @@ class MultiplayerLevelSelectGui extends GuiImage {
var updatePlayerCountFn:(Int, Int, Int, Int) -> Void;
var innerCtrl:GuiControl;
var inviteVisibility:Bool = true;
var chatWnd:ChatCtrl;
static var custSelected:Bool = false;
static var custPath:String;
@ -208,6 +209,12 @@ class MultiplayerLevelSelectGui extends GuiImage {
return t;
}
chatWnd = new ChatCtrl();
chatWnd.horizSizing = Left;
chatWnd.position = new Vector(330, 58);
chatWnd.extent = new Vector(200, 250);
innerCtrl.addChild(chatWnd);
playerList = new GuiMLTextListCtrl(arial14, playerListArr.map(player -> {
return '<img src="${player.state ? "ready" : "notready"}"></img><img src="${platformToString(player.platform)}"></img>${player.name}';
}), imgLoader);
@ -523,9 +530,18 @@ class MultiplayerLevelSelectGui extends GuiImage {
updatePlayerCountFn(pub, priv, publicTotal, privateTotal);
}
public function addChatMessage(str:String) {
this.chatWnd.addChatMessage(str);
}
override function dispose() {
super.dispose();
playSelectedLevel = null;
setLevelFn = null;
}
override function update(dt:Float, mouseState:MouseState) {
this.chatWnd.updateChat(dt);
super.update(dt, mouseState);
}
}

View file

@ -1,5 +1,6 @@
package gui;
import gui.GuiControl.MouseState;
import net.NetCommands;
import hxd.Key;
import net.NetPacket.ScoreboardPacket;
@ -9,9 +10,6 @@ import src.ProfilerUI;
import hxd.App;
import hxd.res.Image;
import hxd.Window;
import h3d.shader.AlphaMult;
import h3d.shader.ColorKey;
import hxd.snd.WavData;
import gui.GuiControl.HorizSizing;
import src.TimeState;
import format.gif.Data.Block;
@ -55,13 +53,6 @@ class PlayerInfo {
var score:Int;
}
@:publicFields
@:structInit
class ChatMessage {
var text:String;
var sendTime:Float;
}
class PlayGui {
var scene2d:h2d.Scene;
@ -103,6 +94,7 @@ class PlayGui {
var playGuiCtrlOuter:GuiControl;
var playGuiCtrl:GuiControl;
var chatCtrl:ChatCtrl;
var resizeEv:Void->Void;
var resizeControlEvents:Array<Void->Void> = [];
@ -115,15 +107,6 @@ class PlayGui {
var totalGems:Int = 0;
var chatHudCtrl:GuiControl;
var chatHud:GuiMLText;
var chatHudBg:GuiMLText;
var chatHudInput:GuiTextInput;
var chatInputBg:GuiImage;
var chatInputBgText:GuiText;
var chats:Array<ChatMessage>;
var chatFocused:Bool = false;
public function dispose() {
if (_init) {
playGuiCtrlOuter.dispose();
@ -140,12 +123,9 @@ class PlayGui {
playerListScoresShadowCtrl.dispose();
playerListScoresShadowCtrl = null;
}
if (chatHudCtrl != null) {
chatHudCtrl.dispose();
chatHudCtrl = null;
chatHud.dispose();
chatHud = null;
chats = null;
if (chatCtrl != null) {
chatCtrl.dispose();
chatCtrl = null;
}
for (textureResource in textureResources) {
@ -675,127 +655,15 @@ class PlayGui {
}
public function initChatHud() {
var arial14fontdata = ResourceLoader.getFileEntry("data/font/Arial Bold.fnt");
var arial14b = new BitmapFont(arial14fontdata.entry);
@:privateAccess arial14b.loader = ResourceLoader.loader;
var arial14 = arial14b.toSdfFont(cast 15 * Settings.uiScale, MultiChannel);
this.chatHudCtrl = new GuiControl();
this.chatHudCtrl.position = new Vector(playGuiCtrl.extent.x - 201, 150);
this.chatHudCtrl.extent = new Vector(200, 250);
this.chatHudCtrl.horizSizing = Left;
this.playGuiCtrl.addChild(chatHudCtrl);
this.chats = [];
this.chatHudBg = new GuiMLText(arial14, (s) -> arial14);
this.chatHudBg.position = new Vector(1, 21);
this.chatHudBg.extent = new Vector(200, 250);
this.chatHudBg.text.textColor = 0;
this.chatHudCtrl.addChild(chatHudBg);
this.chatHud = new GuiMLText(arial14, (s) -> arial14);
this.chatHud.position = new Vector(0, 20);
this.chatHud.extent = new Vector(200, 250);
this.chatHudCtrl.addChild(chatHud);
this.chatInputBg = new GuiImage(ResourceLoader.getResource('data/ui/xbox/fade_black.png', ResourceLoader.getImage, this.imageResources).toTile());
this.chatInputBg.position = new Vector(0, 0);
this.chatInputBg.extent = new Vector(200, 20);
this.chatHudCtrl.addChild(chatInputBg);
this.chatInputBgText = new GuiText(arial14);
this.chatInputBgText.position = new Vector(0, 0);
this.chatInputBgText.extent = new Vector(200, 20);
this.chatInputBg.addChild(chatInputBgText);
this.chatInputBgText.text.textColor = 0xF29515;
this.chatInputBgText.text.text = "Chat:";
this.chatHudInput = new GuiTextInput(arial14);
this.chatHudInput.position = new Vector(40, 0);
this.chatHudInput.extent = new Vector(160, 20);
@:privateAccess this.chatHudInput.text.interactive.forceAnywherefocus = true;
this.chatHudCtrl.addChild(chatHudInput);
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
var sendText = "";
this.chatHudInput.text.onFocus = (e) -> {
this.chatInputBgText.text.visible = true;
this.chatInputBg.bmp.visible = true;
chatFocused = true;
}
this.chatHudInput.text.onFocusLost = (e) -> {
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
sendText = "";
chatFocused = false;
}
this.chatHudInput.text.onKeyDown = (e) -> {
if (e.keyCode == Key.ENTER) {
sendText = '<font color="#F29515">${StringTools.htmlEscape(Settings.highscoreName.substr(0, 20))}:</font> ${StringTools.htmlEscape(this.chatHudInput.text.text.substr(0, 50))}';
if (Net.isClient) {
NetCommands.sendChatMessage(StringTools.htmlEscape(sendText));
}
if (Net.isHost) {
NetCommands.sendServerChatMessage(StringTools.htmlEscape(sendText));
}
this.chatHudInput.text.text = "";
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
chatFocused = false;
}
if (e.keyCode == Key.ESCAPE) {
this.chatHudInput.text.text = "";
this.chatInputBgText.text.visible = false;
this.chatInputBg.bmp.visible = false;
chatFocused = false;
@:privateAccess Key.keyPressed[Key.ESCAPE] = 0; // consume escape
}
}
this.chatHud.text.text = "";
this.chatCtrl = new ChatCtrl();
this.chatCtrl.position = new Vector(playGuiCtrl.extent.x - 201, 150);
this.chatCtrl.extent = new Vector(200, 250);
this.chatCtrl.horizSizing = Left;
this.playGuiCtrl.addChild(chatCtrl);
}
public inline function isChatFocused() {
return chatFocused;
}
public function addChatMessage(text:String) {
var realText = StringTools.htmlUnescape(text);
this.chats.push({
text: realText,
sendTime: MarbleGame.instance.world.timeState.timeSinceLoad
});
if (this.chats.length > 10) {
this.chats = this.chats.slice(this.chats.length - 10);
}
redrawChatMessages();
}
function redrawChatMessages() {
var joined = this.chats.map(x -> x.text).join("<br/>");
this.chatHud.text.text = joined;
this.chatHudBg.text.text = StringTools.replace(joined, '#F29515', '#000000');
}
function tickChats(timeState:TimeState) {
var needsRedraw = false;
while (this.chats.length > 0) {
if (this.chats[0].sendTime + 10 < timeState.timeSinceLoad) {
this.chats.shift();
needsRedraw = true;
} else {
break;
}
}
if (needsRedraw) {
redrawChatMessages();
}
return this.chatCtrl?.chatFocused;
}
var blastValue:Float = 0;
@ -1249,6 +1117,10 @@ class PlayGui {
timerNumbers[6].anim.currentFrame = thousandth;
}
public inline function addChatMessage(str:String) {
this.chatCtrl.addChatMessage(str);
}
public function render(engine:h3d.Engine) {
// Do nothing
}
@ -1259,15 +1131,7 @@ class PlayGui {
}
this.updateMiddleMessages(timeState.dt);
if (Net.isMP) {
if (!chatFocused) {
if (Key.isPressed(Settings.controlsSettings.chat)) {
if (this.chatHudCtrl != null) {
this.chatHudInput.text.focus();
}
}
}
tickChats(timeState);
this.chatCtrl.updateChat(timeState.dt);
}
}

View file

@ -338,6 +338,10 @@ class NetCommands {
if (MarbleGame.instance.world._ready) {
@:privateAccess MarbleGame.instance.world.playGui.addChatMessage(msg);
}
} else {
if (MarbleGame.canvas.content is MultiplayerLevelSelectGui) {
cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).addChatMessage(msg);
}
}
}
}