From 9cde35c64c9f569055b101a80419d900f58806a9 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 3 May 2018 07:35:39 +0200 Subject: Adding theming, add new theme 'simple' --- include/MessageBoard.hpp | 6 ++ include/Text.hpp | 2 + include/Theme.hpp | 17 ++++ src/Chatbar.cpp | 8 +- src/MessageBoard.cpp | 196 ++++++++++++++++++++++++++++++++--------------- src/Text.cpp | 24 ++++-- src/Theme.cpp | 16 ++++ 7 files changed, 196 insertions(+), 73 deletions(-) create mode 100644 include/Theme.hpp create mode 100644 src/Theme.cpp diff --git a/include/MessageBoard.hpp b/include/MessageBoard.hpp index e84396d..a4dc5a6 100644 --- a/include/MessageBoard.hpp +++ b/include/MessageBoard.hpp @@ -24,6 +24,9 @@ namespace dchat private: void updateStaticContentTexture(const sf::Vector2u &newSize); void addMessage(Message *message); + + void drawDefault(sf::RenderWindow &window, Cache &cache); + void drawSimple(sf::RenderWindow &window, Cache &cache); private: sf::RenderTexture staticContentTexture; bool dirty; @@ -37,5 +40,8 @@ namespace dchat sf::Clock frameTimer; double totalHeight; bool scrollToBottom; + sf::Vector2f backgroundSizeWithoutPadding; + sf::Vector2f backgroundSize; + sf::Vector2f backgroundPos; }; } diff --git a/include/Text.hpp b/include/Text.hpp index 4bb5ec0..016e852 100644 --- a/include/Text.hpp +++ b/include/Text.hpp @@ -24,6 +24,7 @@ namespace dchat void setMaxWidth(float maxWidth); void setCharacterSize(unsigned int characterSize); void setFillColor(sf::Color color); + void setLineSpacing(float lineSpacing); // Warning: won't update until @draw is called float getHeight() const; @@ -61,6 +62,7 @@ namespace dchat bool dirty; bool plainText; float totalHeight; + float lineSpacing; std::vector textElements; }; } diff --git a/include/Theme.hpp b/include/Theme.hpp new file mode 100644 index 0000000..19f3200 --- /dev/null +++ b/include/Theme.hpp @@ -0,0 +1,17 @@ +#pragma once + +namespace dchat +{ + class Theme + { + public: + enum class Type + { + DEFAULT, + SIMPLE + }; + + static Type getType(); + static void setType(Type type); + }; +} diff --git a/src/Chatbar.cpp b/src/Chatbar.cpp index 7f50153..cd2daa4 100644 --- a/src/Chatbar.cpp +++ b/src/Chatbar.cpp @@ -277,18 +277,18 @@ namespace dchat text.setCharacterSize(FONT_SIZE * Settings::getScaling()); const float fontHeight = text.getFont()->getLineSpacing(text.getCharacterSize()); - sf::RectangleShape lineShape(sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - LINE_PADDING_SIDE * 2.0f), LINE_HEIGHT)); + sf::RectangleShape lineShape(sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - LINE_PADDING_SIDE * Settings::getScaling() * 2.0f), LINE_HEIGHT)); lineShape.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(10, 10, 10)); - lineShape.setPosition(ChannelSidePanel::getWidth() + LINE_PADDING_SIDE, floor(windowSize.y - getHeight())); + lineShape.setPosition(ChannelSidePanel::getWidth() + LINE_PADDING_SIDE * Settings::getScaling(), floor(windowSize.y - getHeight())); window.draw(lineShape); - sf::Vector2f inputBackgroundSize(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - PADDING_SIDE * 2.0f), floor(fontHeight * 1.7f + BOX_PADDING_Y * Settings::getScaling() * 2.0f)); + sf::Vector2f inputBackgroundSize(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - PADDING_SIDE * Settings::getScaling() * 2.0f), floor(fontHeight * 1.7f + BOX_PADDING_Y * Settings::getScaling() * 2.0f)); sf::Vector2f backgroundSize(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth()), floor(getHeight() - LINE_HEIGHT)); background.setSize(backgroundSize); background.setPosition(ChannelSidePanel::getWidth(), floor(windowSize.y - backgroundSize.y)); window.draw(background); - sf::Vector2f inputBackgroundPos(floor(ChannelSidePanel::getWidth() + PADDING_SIDE), floor(windowSize.y - inputBackgroundSize.y - PADDING_BOTTOM * Settings::getScaling())); + sf::Vector2f inputBackgroundPos(floor(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling()), floor(windowSize.y - inputBackgroundSize.y - PADDING_BOTTOM * Settings::getScaling())); inputBackground.setSize(inputBackgroundSize); inputBackground.setPosition(inputBackgroundPos); text.setPosition(floor(inputBackgroundPos.x + BOX_PADDING_X), floor(inputBackgroundPos.y + inputBackgroundSize.y * 0.5f - fontHeight * 0.5f)); diff --git a/src/MessageBoard.cpp b/src/MessageBoard.cpp index 1c8c4ad..1e5790c 100644 --- a/src/MessageBoard.cpp +++ b/src/MessageBoard.cpp @@ -7,6 +7,7 @@ #include "../include/ChannelTopPanel.hpp" #include "../include/Chatbar.hpp" #include "../include/ColorScheme.hpp" +#include "../include/Theme.hpp" #include #include #include @@ -24,8 +25,6 @@ namespace dchat }; const float USERNAME_PADDING_BOTTOM = 5.0f; - const float MESSAGE_PADDING_TOP = 25.0f; - const float MESSAGE_PADDING_BOTTOM = 30.0f; const float PADDING_SIDE = 40.0f; const float PADDING_TOP = 0.0f; @@ -90,6 +89,128 @@ namespace dchat scrollToBottom = true; } + void MessageBoard::drawDefault(sf::RenderWindow &window, Cache &cache) + { + const float MESSAGE_PADDING_TOP = 25.0f; + const float MESSAGE_PADDING_BOTTOM = 30.0f; + + const sf::Font *usernameFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); + const int usernameTextCharacterSize = 20 * Settings::getScaling(); + const float usernameTextHeight = usernameFont->getLineSpacing(usernameTextCharacterSize); + + const sf::Font *timestampFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); + const int timestampTextCharacterSize = 15 * Settings::getScaling(); + const float timestampTextHeight = timestampFont->getLineSpacing(timestampTextCharacterSize); + + sf::RectangleShape lineRect(sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * Settings::getScaling() * 2.0f, LINE_HEIGHT)); + lineRect.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(10, 10, 10)); + + sf::Vector2 position(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling(), ChannelTopPanel::getHeight() + PADDING_TOP); + double startHeight = position.y; + position.y += scroll; + usize numMessages = messages.size(); + 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) + { + sf::Text usernameText(message->user->getName(), *usernameFont, usernameTextCharacterSize); + usernameText.setFillColor(sf::Color(15, 192, 252)); + usernameText.setPosition(sf::Vector2f(floor(position.x), 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, 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); + } + } + 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.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) + { + 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; + } + totalHeight = (position.y - scroll) - startHeight; + } + + void MessageBoard::drawSimple(sf::RenderWindow &window, Cache &cache) + { + const float LINE_SPACING = 20.0f * Settings::getScaling(); + const float MESSAGE_PADDING_TOP = 0.0f; + const float MESSAGE_PADDING_BOTTOM = 0.0f; + + const sf::Font *usernameFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); + const int usernameTextCharacterSize = 20 * Settings::getScaling(); + const float usernameTextHeight = usernameFont->getLineSpacing(usernameTextCharacterSize); + const float usernameMaxWidth = usernameTextHeight * 5.0f; + + const sf::Font *timestampFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); + const int timestampTextCharacterSize = 15 * Settings::getScaling(); + const float timestampTextHeight = timestampFont->getLineSpacing(timestampTextCharacterSize); + + sf::Vector2 position(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling() + usernameMaxWidth, ChannelTopPanel::getHeight() + PADDING_TOP); + double startHeight = position.y; + position.y += scroll; + usize numMessages = messages.size(); + 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) + { + string usernameTextStr = message->user->getName(); + usernameTextStr += " - "; + sf::Text usernameText(usernameTextStr, *usernameFont, usernameTextCharacterSize); + usernameText.setFillColor(sf::Color(15, 192, 252)); + usernameText.setPosition(sf::Vector2f(floor(position.x - usernameText.getLocalBounds().width), 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, 30)); + //timestamp.setPosition(sf::Vector2f(floor(position.x - usernameText.getLocalBounds().width + 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); + } + } + + // No need to perform culling here, that is done in @Text draw function + message->text.setCharacterSize(18 * Settings::getScaling()); + message->text.setMaxWidth(backgroundSize.x - usernameMaxWidth * 2.0f); + message->text.setPosition(sf::Vector2f(floor(position.x), floor(position.y))); + message->text.setLineSpacing(LINE_SPACING); + message->text.draw(window, cache); + position.y += (message->text.getHeight() + MESSAGE_PADDING_BOTTOM * Settings::getScaling()); + } + totalHeight = (position.y - scroll) - startHeight; + } + void MessageBoard::processEvent(const sf::Event &event) { if(event.type == sf::Event::MouseButtonPressed) @@ -143,9 +264,9 @@ namespace dchat void MessageBoard::draw(sf::RenderWindow &window, Cache &cache) { auto windowSize = window.getSize(); - sf::Vector2f backgroundSizeWithoutPadding(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth()), floor(windowSize.y - ChannelTopPanel::getHeight() - Chatbar::getHeight())); - sf::Vector2u backgroundSize(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - PADDING_SIDE * 2.0f), floor(windowSize.y - ChannelTopPanel::getHeight() - Chatbar::getHeight() - PADDING_TOP)); - sf::Vector2f backgroundPos(ChannelSidePanel::getWidth(), ChannelTopPanel::getHeight()); + backgroundSizeWithoutPadding = sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth()), floor(windowSize.y - ChannelTopPanel::getHeight() - Chatbar::getHeight())); + backgroundSize = sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - PADDING_SIDE * Settings::getScaling() * 2.0f), floor(windowSize.y - ChannelTopPanel::getHeight() - Chatbar::getHeight() - PADDING_TOP)); + backgroundPos = sf::Vector2f(ChannelSidePanel::getWidth(), ChannelTopPanel::getHeight()); //if(backgroundSize != staticContentTexture.getSize()) // updateStaticContentTexture(backgroundSize); @@ -160,69 +281,20 @@ namespace dchat backgroundRect.setPosition(ChannelSidePanel::getWidth(), ChannelTopPanel::getHeight()); window.draw(backgroundRect); - const sf::Font *usernameFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); - const int usernameTextCharacterSize = 20 * Settings::getScaling(); - const float usernameTextHeight = usernameFont->getLineSpacing(usernameTextCharacterSize); - - const sf::Font *timestampFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); - const int timestampTextCharacterSize = 15 * Settings::getScaling(); - const float timestampTextHeight = timestampFont->getLineSpacing(timestampTextCharacterSize); - double deltaTimeMicro = (double)frameTimer.getElapsedTime().asMicroseconds(); frameTimer.restart(); if(dirty) { - sf::RectangleShape lineRect(sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * 2.0f, LINE_HEIGHT)); - lineRect.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(10, 10, 10)); - - sf::Vector2 position(ChannelSidePanel::getWidth(), ChannelTopPanel::getHeight() + PADDING_TOP); - double startHeight = position.y; - position.y += scroll; - usize numMessages = messages.size(); - for(usize i = 0; i < numMessages; ++i) + switch(Theme::getType()) { - Message *message = messages[i]; - position.y += (MESSAGE_PADDING_TOP * Settings::getScaling()); - if(position.y + usernameTextHeight > 0.0f && position.y < backgroundPos.y + backgroundSize.y) - { - sf::Text usernameText(message->user->getName(), *usernameFont, usernameTextCharacterSize); - usernameText.setFillColor(sf::Color(15, 192, 252)); - usernameText.setPosition(sf::Vector2f(floor(position.x + PADDING_SIDE), 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, 30)); - timestamp.setPosition(sf::Vector2f(floor(position.x + PADDING_SIDE + 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); - } - } - 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 + PADDING_SIDE), floor(position.y))); - 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) - { - lineRect.setPosition(sf::Vector2f(position.x + LINE_SIDE_PADDING, 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; + case Theme::Type::DEFAULT: + drawDefault(window, cache); + break; + case Theme::Type::SIMPLE: + drawSimple(window, cache); + break; } - totalHeight = (position.y - scroll) - startHeight; } scroll += scrollSpeed; @@ -240,7 +312,7 @@ namespace dchat if(abs(scrollSpeed - deltaTimeScrollMultiplier) <= deltaTimeScrollMultiplier) scrollSpeed = 0.0; - double textOverflow = backgroundSize.y - totalHeight; + double textOverflow = (double)backgroundSize.y - totalHeight; if(scroll > 0.0 || textOverflow > 0.0) { scroll = 0.0; diff --git a/src/Text.cpp b/src/Text.cpp index 3cafc69..b22a27d 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -31,7 +31,8 @@ namespace dchat color(sf::Color::White), dirty(true), plainText(_plainText), - totalHeight(0.0f) + totalHeight(0.0f), + lineSpacing(0.0f) { setString(_str); } @@ -94,6 +95,15 @@ namespace dchat } } + void Text::setLineSpacing(float lineSpacing) + { + if(lineSpacing != this->lineSpacing) + { + this->lineSpacing = lineSpacing; + dirty = true; + } + } + float Text::getHeight() const { return totalHeight; @@ -203,7 +213,7 @@ namespace dchat if(glyphPos.x > maxWidth) { glyphPos.x = 0.0f; - glyphPos.y += vspace; + glyphPos.y += vspace + lineSpacing; } continue; @@ -244,12 +254,12 @@ namespace dchat case '\n': { glyphPos.x = 0.0f; - glyphPos.y += vspace; + glyphPos.y += vspace + lineSpacing; continue; } case '\v': { - glyphPos.y += (vspace * TAB_WIDTH); + glyphPos.y += (vspace * TAB_WIDTH) + lineSpacing; continue; } } @@ -268,7 +278,7 @@ namespace dchat { sf::Vector2f &vertexPos = vertices[vertexOffset + j * 4 + k].position; vertexPos.x -= lastSpacingAccumulatedOffset; - vertexPos.y += vspace; + vertexPos.y += vspace + lineSpacing; } } @@ -279,7 +289,7 @@ namespace dchat else glyphPos.x = 0.0f; - glyphPos.y += vspace; + glyphPos.y += vspace + lineSpacing; } sf::Vector2f vertexTopLeft(glyphPos.x + glyph.bounds.left, glyphPos.y + glyph.bounds.top); @@ -300,7 +310,7 @@ namespace dchat glyphPos.x += glyph.advance; } } - totalHeight = glyphPos.y + vspace; + totalHeight = glyphPos.y + lineSpacing + vspace; } void Text::draw(sf::RenderTarget &target, Cache &cache) diff --git a/src/Theme.cpp b/src/Theme.cpp new file mode 100644 index 0000000..c882cc4 --- /dev/null +++ b/src/Theme.cpp @@ -0,0 +1,16 @@ +#include "../include/Theme.hpp" + +namespace dchat +{ + static Theme::Type type = Theme::Type::DEFAULT; + + Theme::Type Theme::getType() + { + return type; + } + + void Theme::setType(Type _type) + { + type = _type; + } +} -- cgit v1.2.3