From 3c4fae07f53d19daad22aaa39796c64055297a38 Mon Sep 17 00:00:00 2001
From: Quentin Bazin <quent42340@gmail.com>
Date: Sat, 22 Feb 2020 01:00:42 +0900
Subject: [PATCH] [Text] Added the possibility to cut a line in the middle if
 it's too long.

---
 client/include/gui/Text.hpp        |  6 +++++-
 client/include/hud/Chat.hpp        |  2 ++
 client/include/hud/ChatMessage.hpp |  4 +++-
 client/source/gui/Text.cpp         | 17 +++++++++++------
 client/source/hud/Chat.cpp         |  6 ++++--
 client/source/hud/ChatMessage.cpp  |  7 ++++---
 6 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/client/include/gui/Text.hpp b/client/include/gui/Text.hpp
index c98b13038..599f7a40e 100644
--- a/client/include/gui/Text.hpp
+++ b/client/include/gui/Text.hpp
@@ -43,7 +43,9 @@ class Text : public gk::Drawable, public gk::Transformable {
 		void setBackgroundColor(const gk::Color &color) { m_background.setFillColor(color); }
 		void setBackgroundSize(unsigned int width, unsigned int height) { m_background.setSize(width, height); }
 
-		void setPadding(int x, int y) { m_padding.x = x; m_padding.y = y; }
+		void setPadding(int x, int y) { m_padding.x = x; m_padding.y = y; updateTextSprites(); }
+
+		void setMaxLineLength(unsigned int maxLineLength) { m_maxLineLength = maxLineLength; updateTextSprites(); }
 
 	private:
 		void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
@@ -65,6 +67,8 @@ class Text : public gk::Drawable, public gk::Transformable {
 		gk::Color m_color = gk::Color::White;
 
 		gk::RectangleShape m_background;
+
+		unsigned int m_maxLineLength = 0;
 };
 
 #endif // TEXT_HPP_
diff --git a/client/include/hud/Chat.hpp b/client/include/hud/Chat.hpp
index 844795402..833d74c01 100644
--- a/client/include/hud/Chat.hpp
+++ b/client/include/hud/Chat.hpp
@@ -39,6 +39,8 @@ class Chat : public gk::Drawable, public gk::Transformable {
 		void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
 
 		std::deque<ChatMessage> m_chatMessages;
+
+		u32 m_posY = 0;
 };
 
 #endif // CHAT_HPP_
diff --git a/client/include/hud/ChatMessage.hpp b/client/include/hud/ChatMessage.hpp
index 727117094..bb33a0b00 100644
--- a/client/include/hud/ChatMessage.hpp
+++ b/client/include/hud/ChatMessage.hpp
@@ -27,10 +27,12 @@
 
 class ChatMessage : public gk::Drawable, public gk::Transformable {
 	public:
-		ChatMessage(u16 clientID, const std::string &message, u32 messageCount);
+		ChatMessage(u16 clientID, const std::string &message, u32 posY);
 
 		void setVisible(bool isVisible) { m_isVisible = isVisible; }
 
+		const Text &text() const { return m_text; }
+
 	private:
 		void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
 
diff --git a/client/source/gui/Text.cpp b/client/source/gui/Text.cpp
index 68f053af8..2c94981dd 100644
--- a/client/source/gui/Text.cpp
+++ b/client/source/gui/Text.cpp
@@ -62,12 +62,12 @@ void Text::draw(gk::RenderTarget &target, gk::RenderStates states) const {
 void Text::updateTextSprites() {
 	m_textSprites.clear();
 
-	int x = 0;
-	int y = 0;
-	int maxX = 0;
+	unsigned int x = 0;
+	unsigned int y = 0;
+	unsigned int maxX = 0;
 	gk::Color color = gk::Color{70, 70, 70, 255};
 	for(char c : m_text) {
-		if (c == '\n') {
+		if (c == '\n' || (m_maxLineLength && x + m_charWidth[(u8)c] >= m_maxLineLength)) {
 			y += 9;
 			x = 0;
 			continue;
@@ -84,7 +84,7 @@ void Text::updateTextSprites() {
 	y = 0;
 	color = m_color;
 	for(char c : m_text) {
-		if (c == '\n') {
+		if (c == '\n' || (m_maxLineLength && x + m_charWidth[(u8)c] >= m_maxLineLength)) {
 			maxX = std::max(x, maxX);
 			y += 9;
 			x = 0;
@@ -102,7 +102,12 @@ void Text::updateTextSprites() {
 	}
 
 	m_size.x = std::max(x, maxX);
-	m_size.y = 8 + y * 9;
+	m_size.y = y + 9;
+
+	unsigned int backgroundX = std::max<int>(m_background.getSize().x, m_size.x + m_padding.x);
+	unsigned int backgroundY = std::max<int>(m_background.getSize().y, m_size.y + m_padding.y);
+
+	m_background.setSize(backgroundX, backgroundY);
 }
 
 // FIXME: Since I use the font from Minecraft assets, I needed to use
diff --git a/client/source/hud/Chat.cpp b/client/source/hud/Chat.cpp
index 6c1f1bb4b..7fc02555c 100644
--- a/client/source/hud/Chat.cpp
+++ b/client/source/hud/Chat.cpp
@@ -32,9 +32,11 @@ Chat::Chat(Client &client) {
 		std::string message;
 		packet >> clientID >> message;
 
-		m_chatMessages.emplace_back(clientID, message, m_chatMessages.size());
+		m_chatMessages.emplace_back(clientID, message, m_posY);
 
-		move(0, -10);
+		m_posY += m_chatMessages.back().text().getSize().y + 1;
+
+		move(0, -m_chatMessages.back().text().getSize().y - 1);
 	});
 }
 
diff --git a/client/source/hud/ChatMessage.cpp b/client/source/hud/ChatMessage.cpp
index 7bc4c50fa..3da918fd9 100644
--- a/client/source/hud/ChatMessage.cpp
+++ b/client/source/hud/ChatMessage.cpp
@@ -22,11 +22,12 @@
  */
 #include "ChatMessage.hpp"
 
-ChatMessage::ChatMessage(u16 clientID, const std::string &message, u32 messageCount) {
+ChatMessage::ChatMessage(u16 clientID, const std::string &message, u32 posY) {
 	m_text.setText("<Client " + std::to_string(clientID) + "> " + message);
-	m_text.setPosition(0, 10 * messageCount);
+	m_text.setPosition(0, posY);
 	m_text.setBackgroundColor(gk::Color{0, 0, 0, 127});
 	m_text.setBackgroundSize(300, 10);
+	m_text.setMaxLineLength(300);
 	m_text.setPadding(1, 1);
 
 	m_timer.reset();
@@ -34,7 +35,7 @@ ChatMessage::ChatMessage(u16 clientID, const std::string &message, u32 messageCo
 }
 
 void ChatMessage::draw(gk::RenderTarget &target, gk::RenderStates states) const {
-	if (m_timer.time() <= 5000 || m_isVisible)
+	if (m_timer.time() <= 10000 || m_isVisible)
 		target.draw(m_text, states);
 }