diff options
Diffstat (limited to 'src/MessageBoard.cpp')
-rw-r--r-- | src/MessageBoard.cpp | 108 |
1 files changed, 80 insertions, 28 deletions
diff --git a/src/MessageBoard.cpp b/src/MessageBoard.cpp index d73dc84..8572873 100644 --- a/src/MessageBoard.cpp +++ b/src/MessageBoard.cpp @@ -8,6 +8,7 @@ #include "../include/Chatbar.hpp" #include "../include/ColorScheme.hpp" #include "../include/Theme.hpp" +#include <SFML/Graphics/CircleShape.hpp> #include <SFML/Graphics/RectangleShape.hpp> #include <SFML/Graphics/Sprite.hpp> #include <SFML/Window/Mouse.hpp> @@ -30,7 +31,9 @@ namespace dchat const float PADDING_TOP = 0.0f; const float LINE_SIDE_PADDING = 20.0f; const float LINE_HEIGHT = 1.0f; - const float USERNAME_TIMESTAMP_SIDE_PADDING = 10.0f; + const float USERNAME_TIMESTAMP_SIDE_PADDING = 15.0f; + const float AVATAR_DIAMETER = 70.0f; + const float AVATAR_PADDING_SIDE = 30.0f; const double SCROLL_MAX_SPEED = 20.0; MessageBoard::MessageBoard(const sf::Vector2u &size) : @@ -77,7 +80,7 @@ namespace dchat const float usernameTextHeight = usernameFont->getLineSpacing(usernameTextCharacterSize); const sf::Font *timestampFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); - const int timestampTextCharacterSize = 15 * Settings::getScaling(); + const int timestampTextCharacterSize = (float)usernameTextCharacterSize * 0.75f; const float timestampTextHeight = timestampFont->getLineSpacing(timestampTextCharacterSize); sf::RectangleShape lineRect(sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * Settings::getScaling() * 2.0f, LINE_HEIGHT)); @@ -90,45 +93,94 @@ namespace dchat for(usize i = 0; i < numMessages; ++i) { Message *message = messages[i]; - position.y += (MESSAGE_PADDING_TOP * Settings::getScaling()); - if(position.y + usernameTextHeight > 0.0f && position.y < backgroundPos.y + backgroundSize.y) + + bool mergeTextWithPrev = false; + if(i > 0) { - sf::Text usernameText(sf::String::fromUtf8(message->user->getName().begin(), message->user->getName().end()), *usernameFont, usernameTextCharacterSize); - usernameText.setFillColor(sf::Color(15, 192, 252)); - usernameText.setPosition(sf::Vector2f(floor(position.x), floor(position.y))); - window.draw(usernameText); + Message *prevMessage = messages[i - 1]; + mergeTextWithPrev = prevMessage->user == message->user && (message->timestampSeconds == 0 || message->timestampSeconds - prevMessage->timestampSeconds); + } + mergeTextWithPrev = false; + + if(!mergeTextWithPrev) + { + position.y += (MESSAGE_PADDING_TOP * Settings::getScaling()); + if(position.y + usernameTextHeight > 0.0f && position.y < backgroundPos.y + backgroundSize.y) + { + sf::Text usernameText(sf::String::fromUtf8(message->user->getName().begin(), message->user->getName().end()), *usernameFont, usernameTextCharacterSize); + usernameText.setFillColor(sf::Color(15, 192, 252)); + usernameText.setPosition(sf::Vector2f(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()), floor(position.y))); + window.draw(usernameText); + + if(message->timestampSeconds) + { + time_t time = (time_t)message->timestampSeconds; + struct tm *localTimePtr = localtime(&time); + char date[30]; + strftime(date, sizeof(date), "%Y-%m-%d at %T", localTimePtr); + + sf::Text timestamp(date, *timestampFont, timestampTextCharacterSize); + timestamp.setFillColor(ColorScheme::getTextRegularColor() * sf::Color(255, 255, 255, 50)); + timestamp.setPosition(sf::Vector2f(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling() + usernameText.getLocalBounds().width + USERNAME_TIMESTAMP_SIDE_PADDING * Settings::getScaling()), floor(position.y + 2.0f * Settings::getScaling() + usernameTextHeight * 0.5f - timestampTextHeight * 0.5f))); + window.draw(timestamp); + } + } - if(message->timestampSeconds) + const ContentByUrlResult avatarResult = cache.getContentByUrl(message->user->avatarUrl); + if(avatarResult.type == ContentByUrlResult::Type::CACHED) { - time_t time = (time_t)message->timestampSeconds; - struct tm *localTimePtr = localtime(&time); - char date[30]; - strftime(date, sizeof(date), "%Y-%m-%d at %T", localTimePtr); + sf::Shader *circleShader = ResourceCache::getShader("shaders/circleMask.glsl", sf::Shader::Fragment); + circleShader->setUniform("texture", sf::Shader::CurrentTexture); - sf::Text timestamp(date, *timestampFont, timestampTextCharacterSize); - timestamp.setFillColor(ColorScheme::getTextRegularColor() * sf::Color(255, 255, 255, 30)); - timestamp.setPosition(sf::Vector2f(floor(position.x + usernameText.getLocalBounds().width + USERNAME_TIMESTAMP_SIDE_PADDING * Settings::getScaling()), floor(position.y + 2.0f * Settings::getScaling() + usernameTextHeight * 0.5f - timestampTextHeight * 0.5f))); - window.draw(timestamp); + if(avatarResult.cachedType == ContentByUrlResult::CachedType::TEXTURE) + { + // TODO: Store this sprite somewhere, might not be efficient to create a new sprite object every frame + sf::Sprite sprite(*avatarResult.texture); + auto textureSize = avatarResult.texture->getSize(); + sprite.setPosition(sf::Vector2f(floor(position.x), floor(position.y))); + sprite.setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)textureSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)textureSize.y)); + window.draw(sprite, circleShader); + } + else if(avatarResult.cachedType == ContentByUrlResult::CachedType::GIF) + { + auto gifSize = avatarResult.gif->getSize(); + avatarResult.gif->setPosition(sf::Vector2f(floor(position.x), floor(position.y))); + avatarResult.gif->setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.y)); + avatarResult.gif->draw(window, circleShader); + } + } + else + { + sf::CircleShape avatarCircle(AVATAR_DIAMETER * 0.5f * Settings::getScaling(), 60 * Settings::getScaling()); + avatarCircle.setPosition(sf::Vector2f(floor(position.x), floor(position.y))); + window.draw(avatarCircle); } + + position.y += usernameTextHeight + USERNAME_PADDING_BOTTOM * Settings::getScaling(); } - position.y += usernameTextHeight + USERNAME_PADDING_BOTTOM * Settings::getScaling(); // No need to perform culling here, that is done in @Text draw function message->text.setCharacterSize(18 * Settings::getScaling()); - message->text.setMaxWidth(backgroundSize.x); - message->text.setPosition(sf::Vector2f(floor(position.x), floor(position.y))); + message->text.setMaxWidth(backgroundSize.x - (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()); + message->text.setPosition(sf::Vector2f(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()), floor(position.y))); message->text.setLineSpacing(LINE_SPACING); message->text.draw(window, cache); - position.y += (message->text.getHeight() + MESSAGE_PADDING_BOTTOM * Settings::getScaling()); - - if(position.y + LINE_HEIGHT > 0.0f && position.y < backgroundPos.y + backgroundSize.y && i + 1 != numMessages) + position.y += message->text.getHeight(); + if(!mergeTextWithPrev) { - lineRect.setPosition(sf::Vector2f(position.x + LINE_SIDE_PADDING * Settings::getScaling() - PADDING_SIDE * Settings::getScaling(), floor(position.y))); - window.draw(lineRect); - //drawGradientLine(sf::Vector2f(position.x + LINE_SIDE_PADDING, floor(position.y)), sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * 2.0f, LINE_HEIGHT), LINE_COLOR, window); - } + position.y += (MESSAGE_PADDING_BOTTOM * Settings::getScaling()); - position.y += LINE_HEIGHT; + if(position.y + LINE_HEIGHT > 0.0f && position.y < backgroundPos.y + backgroundSize.y && i + 1 != numMessages) + { + lineRect.setPosition(sf::Vector2f(position.x + LINE_SIDE_PADDING * Settings::getScaling() - PADDING_SIDE * Settings::getScaling(), floor(position.y))); + window.draw(lineRect); + //drawGradientLine(sf::Vector2f(position.x + LINE_SIDE_PADDING, floor(position.y)), sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * 2.0f, LINE_HEIGHT), LINE_COLOR, window); + } + + position.y += LINE_HEIGHT; + } + else + position.y += LINE_SPACING; } totalHeight = (position.y - scroll) - startHeight; } |