#include "../include/MessageBoard.hpp" #include "../include/Settings.hpp" #include "../include/ResourceCache.hpp" #include "../include/Gif.hpp" #include #include #include #include #include #include using namespace std; namespace dchat { const sf::Color BACKGROUND_COLOR(40, 40, 40); const float USERNAME_PADDING_BOTTOM = 0.0f; const float MESSAGE_PADDING_BOTTOM = 20.0f; MessageBoard::MessageBoard(const sf::Vector2u &size) : selectingText(false), leftMouseButtonPressed(false) { updateStaticContentTexture(size); } MessageBoard::~MessageBoard() { for(Message *message : messages) { delete message; } } void MessageBoard::updateStaticContentTexture(const sf::Vector2u &newSize) { if(!staticContentTexture.create(newSize.x, newSize.y)) throw std::runtime_error("Failed to create render target for message board!"); dirty = true; } void MessageBoard::addMessage(Message *message) { messages.push_back(message); dirty = true; } void MessageBoard::processEvent(const sf::Event &event) { if(event.type == sf::Event::MouseButtonPressed) { if(event.mouseButton.button == sf::Mouse::Button::Left) { leftMouseButtonPressed = true; mousePos.x = event.mouseButton.x; mousePos.y = event.mouseButton.y; } } else if(event.type == sf::Event::MouseButtonReleased) { if(event.mouseButton.button == sf::Mouse::Button::Left) { leftMouseButtonPressed = false; mousePos.x = event.mouseButton.x; mousePos.y = event.mouseButton.y; } } else if(event.type == sf::Event::LostFocus) { leftMouseButtonPressed = false; } else if(event.type == sf::Event::MouseMoved) { mousePos.x = event.mouseMove.x; mousePos.y = event.mouseMove.y; } if(selectingText && !leftMouseButtonPressed) { selectingText = false; } else if(!selectingText && leftMouseButtonPressed) { selectingText = true; selectingTextStart.x = mousePos.x; selectingTextStart.y = mousePos.y; } } void MessageBoard::draw(sf::RenderWindow &window, Cache &cache) { auto windowSize = window.getSize(); sf::Vector2u backgroundSize(floor(windowSize.x * 0.7f), floor(windowSize.y)); sf::Vector2f backgroundPos(floor(windowSize.x * 0.5f - backgroundSize.x * 0.5f), 0.0f); if(backgroundSize != staticContentTexture.getSize()) updateStaticContentTexture(backgroundSize); // TODO: Remove this when dchat::Text can render to static and dynamic render target dirty = true; if(dirty) staticContentTexture.clear(BACKGROUND_COLOR); const sf::Font &usernameFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); if(dirty) { sf::Vector2f position; for(Message *message : messages) { sf::Text usernameText(message->user->getName(), usernameFont, 20 * Settings::getScaling()); usernameText.setFillColor(sf::Color(15, 192, 252)); usernameText.setPosition(position); staticContentTexture.draw(usernameText); position.y += usernameText.getFont()->getLineSpacing(usernameText.getCharacterSize()) + USERNAME_PADDING_BOTTOM; message->text.setMaxWidth(backgroundSize.x); message->text.setPosition(position); message->text.draw(staticContentTexture, cache); position.y += message->text.getHeight() + MESSAGE_PADDING_BOTTOM; } } staticContentTexture.display(); dirty = false; // TODO: Save this, expensive to create on fly? sf::Sprite textureSprite(staticContentTexture.getTexture()); textureSprite.setPosition(backgroundPos); window.draw(textureSprite); if(!selectingText) return; sf::Vector2f selectionRectStart(min((float)mousePos.x, selectingTextStart.x), min((float)mousePos.y, selectingTextStart.y)); sf::Vector2f selectionRectEnd(max((float)mousePos.x, selectingTextStart.x), max((float)mousePos.y, selectingTextStart.y)); sf::FloatRect selectionRect(selectionRectStart, selectionRectEnd - selectionRectStart); } }