From 9ebc3e3f5cf4847239d04cf5b3b01d0b1855a039 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 7 May 2018 06:34:22 +0200 Subject: Continue text edit, add avatar (image, but not way to change avatar) --- include/Channel.hpp | 2 +- include/Gif.hpp | 2 +- include/ResourceCache.hpp | 3 ++ include/Text.hpp | 2 +- include/User.hpp | 1 + shaders/circleMask.glsl | 10 +++++ src/Channel.cpp | 24 ++++------- src/ChannelSidePanel.cpp | 7 ++- src/ChannelTopPanel.cpp | 14 +++--- src/ColorScheme.cpp | 6 +-- src/Gif.cpp | 4 +- src/MessageBoard.cpp | 108 ++++++++++++++++++++++++++++++++++------------ src/ResourceCache.cpp | 20 +++++++++ src/Text.cpp | 37 ++++++++++++---- src/UsersSidePanel.cpp | 13 +++++- 15 files changed, 182 insertions(+), 71 deletions(-) create mode 100644 shaders/circleMask.glsl diff --git a/include/Channel.hpp b/include/Channel.hpp index 17128fd..1acfcd1 100644 --- a/include/Channel.hpp +++ b/include/Channel.hpp @@ -40,7 +40,7 @@ namespace dchat OnlineUser* getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey); const odhtdb::DatabaseNode& getNodeInfo() const; - // If timestamp is 0, then timestamp is not used + // If timestamp is 0, then current time is used void addLocalMessage(const std::string &msg, User *owner, u64 timestampSeconds = 0); void addMessage(const std::string &msg); void addUserLocally(User *user); diff --git a/include/Gif.hpp b/include/Gif.hpp index 84299e9..8f5d4e7 100644 --- a/include/Gif.hpp +++ b/include/Gif.hpp @@ -32,7 +32,7 @@ namespace dchat void setPosition(const sf::Vector2f &position); void setScale(const sf::Vector2f &scale); - void draw(sf::RenderTarget &target); + void draw(sf::RenderTarget &target, const sf::RenderStates &renderStates = sf::RenderStates::Default); static bool isDataGif(const StringView &data); private: diff --git a/include/ResourceCache.hpp b/include/ResourceCache.hpp index de35500..75ebd88 100644 --- a/include/ResourceCache.hpp +++ b/include/ResourceCache.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -21,5 +22,7 @@ namespace dchat // Throws FailedToLoadResourceException on failure static sf::Texture* getTexture(const std::string &filepath); + + static sf::Shader* getShader(const std::string &filepath, sf::Shader::Type shaderType); }; } diff --git a/include/Text.hpp b/include/Text.hpp index 9df973d..0bc3ced 100644 --- a/include/Text.hpp +++ b/include/Text.hpp @@ -87,7 +87,7 @@ namespace dchat bool plainText; bool editable; CaretMoveDirection caretMoveDirection; - float totalHeight; + sf::FloatRect boundingBox; float lineSpacing; std::vector textElements; diff --git a/include/User.hpp b/include/User.hpp index 821be6f..a83b9dc 100644 --- a/include/User.hpp +++ b/include/User.hpp @@ -24,6 +24,7 @@ namespace dchat virtual const std::string& getName() const = 0; const Type type; + std::string avatarUrl; }; class OnlineUser : public User diff --git a/shaders/circleMask.glsl b/shaders/circleMask.glsl new file mode 100644 index 0000000..7595ea9 --- /dev/null +++ b/shaders/circleMask.glsl @@ -0,0 +1,10 @@ +uniform sampler2D texture; + +void main() +{ + vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); + vec2 pixelOffset = gl_TexCoord[0].xy - vec2(0.5, 0.5); + float dist = sqrt(dot(pixelOffset, pixelOffset)); + dist = smoothstep(0.47, 0.5, dist); + gl_FragColor = gl_Color * pixel * vec4(1.0, 1.0, 1.0, 1.0 - dist); +} diff --git a/src/Channel.cpp b/src/Channel.cpp index 2bd1b0b..185c544 100644 --- a/src/Channel.cpp +++ b/src/Channel.cpp @@ -19,21 +19,11 @@ namespace dchat localUser(_localUser ? _localUser : new OfflineUser("You")) { addUserLocally(localUser); - { - Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif) deaf [emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)"); - messageBoard.addMessage(message); - } - - { - Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif)[emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)"); - messageBoard.addMessage(message); - } - - { - Message *message = new Message(&systemUser, u8"pepedab https://discordemoji.com/assets/emoji/PepeDab.gif coggers https://discordemoji.com/assets/emoji/COGGERS.gif check out this url http://www.grandtournation.com/6808/start-date-of-the-grand-tour-season-3-confirmed-mark-your-calendars/ owo"); - message->text.setEditable(true); - messageBoard.addMessage(message); - } + localUser->avatarUrl = "https://archive.lainchan.jp/diy/thumb/1445879602710.png"; + + addLocalMessage(u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif) deaf [emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)", &systemUser); + addLocalMessage(u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif)[emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)", &systemUser); + addLocalMessage(u8"pepedab https://discordemoji.com/assets/emoji/PepeDab.gif coggers https://discordemoji.com/assets/emoji/COGGERS.gif check out this url http://www.grandtournation.com/6808/start-date-of-the-grand-tour-season-3-confirmed-mark-your-calendars/ owo", &systemUser); if(database) database->seed(databaseNodeInfo); @@ -91,6 +81,10 @@ namespace dchat void Channel::addLocalMessage(const std::string &msg, User *owner, u64 timestampSeconds) { assert(owner); + if(timestampSeconds == 0) + { + timestampSeconds = time(NULL); + } messageBoard.addMessage(new Message(owner, msg, timestampSeconds)); } diff --git a/src/ChannelSidePanel.cpp b/src/ChannelSidePanel.cpp index 89a550a..58cb9bc 100644 --- a/src/ChannelSidePanel.cpp +++ b/src/ChannelSidePanel.cpp @@ -33,11 +33,10 @@ namespace dchat { float posY = ChannelTopPanel::getHeight(); auto windowSize = window.getSize(); - sf::RectangleShape rect(sf::Vector2f(getWidth(), windowSize.y - ChannelTopPanel::getHeight())); - rect.setPosition(0.0f, posY); + sf::RectangleShape rect(sf::Vector2f(getWidth(), windowSize.y)); + rect.setPosition(0.0f, 0.0f); rect.setFillColor(ColorScheme::getPanelColor()); window.draw(rect); - //posY += 10.0f; const sf::Font *font = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); const float fontSize = FONT_SIZE * Settings::getScaling(); @@ -49,7 +48,7 @@ namespace dchat { if(channel == Channel::getCurrent()) { - rect.setFillColor(ColorScheme::getPanelColor() + sf::Color(15, 15, 15)); + rect.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(15, 15, 15)); rect.setSize(sf::Vector2f(getWidth(), channelBoxHeight)); rect.setPosition(sf::Vector2f(0.0f, position.y)); window.draw(rect); diff --git a/src/ChannelTopPanel.cpp b/src/ChannelTopPanel.cpp index d597353..1781e74 100644 --- a/src/ChannelTopPanel.cpp +++ b/src/ChannelTopPanel.cpp @@ -3,6 +3,8 @@ #include "../include/ResourceCache.hpp" #include "../include/Channel.hpp" #include "../include/ColorScheme.hpp" +#include "../include/ChannelSidePanel.hpp" +#include "../include/UsersSidePanel.hpp" #include #include @@ -17,6 +19,7 @@ namespace dchat const float BOTTOM_LINE_HEIGHT = 2.0f; const float PADDING_TOP = 20.0f; const float PADDING_BOTTOM = PADDING_TOP; + const float PADDING_SIDE = 20.0f; static void drawGradientLine(const sf::Vector2f &position, const sf::Vector2f &size, const LineColor &color, sf::RenderWindow &window) { @@ -37,16 +40,17 @@ namespace dchat void ChannelTopPanel::draw(sf::RenderWindow &window) { - const sf::Color lineSideColor = ColorScheme::getBackgroundColor(); + const sf::Color lineSideColor = ColorScheme::getBackgroundColor() + sf::Color(20, 0, 0); const sf::Color lineCenterColor = lineSideColor + sf::Color(40, 0, 0); auto windowSize = window.getSize(); - sf::RectangleShape rect(sf::Vector2f(windowSize.x, getHeight() - BOTTOM_LINE_HEIGHT)); + sf::RectangleShape rect(sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth()), getHeight() - BOTTOM_LINE_HEIGHT)); + rect.setPosition(ChannelSidePanel::getWidth(), 0.0f); rect.setFillColor(ColorScheme::getBackgroundColor()); window.draw(rect); - sf::Vector2f bottomLinePos(0.0f, getHeight() - BOTTOM_LINE_HEIGHT); - sf::Vector2f bottomLineSize(windowSize.x, BOTTOM_LINE_HEIGHT); + sf::Vector2f bottomLinePos(floor(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling()), getHeight() - BOTTOM_LINE_HEIGHT); + sf::Vector2f bottomLineSize(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - PADDING_SIDE * Settings::getScaling() * 2.0f), BOTTOM_LINE_HEIGHT); LineColor lineColor { @@ -63,7 +67,7 @@ namespace dchat float fontSize = FONT_SIZE * Settings::getScaling(); sf::Text text(str, *ResourceCache::getFont("fonts/Roboto-Regular.ttf"), fontSize); auto textBounds = text.getLocalBounds(); - text.setPosition(floor((float)windowSize.x * 0.5f - textBounds.width * 0.5f), PADDING_TOP); + text.setPosition(floor(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling()), PADDING_TOP); text.setFillColor(ColorScheme::getTextRegularColor()); window.draw(text); } diff --git a/src/ColorScheme.cpp b/src/ColorScheme.cpp index e2138c3..09dde51 100644 --- a/src/ColorScheme.cpp +++ b/src/ColorScheme.cpp @@ -14,7 +14,7 @@ namespace dchat colorSchemeType = type; } - sf::Color ColorScheme::getBackgroundColor(){ return sf::Color(40, 40, 40); } - sf::Color ColorScheme::getPanelColor() { return sf::Color(35, 35, 35); } - sf::Color ColorScheme::getTextRegularColor() { return sf::Color(240, 240, 240); } + sf::Color ColorScheme::getBackgroundColor(){ return sf::Color(54,57,62); } + sf::Color ColorScheme::getPanelColor() { return sf::Color(47,49,54); } + sf::Color ColorScheme::getTextRegularColor() { return sf::Color(255, 255, 255); } } diff --git a/src/Gif.cpp b/src/Gif.cpp index c79153c..69c0be8 100644 --- a/src/Gif.cpp +++ b/src/Gif.cpp @@ -149,7 +149,7 @@ namespace dchat sprite.setScale(scale); } - void Gif::draw(sf::RenderTarget &target) + void Gif::draw(sf::RenderTarget &target, const sf::RenderStates &renderState) { double timeElapsedMilli = (double)frameTimer.getElapsedTime().asMilliseconds(); // If gif is not redrawn for a while, then we reset timer (gif is paused). This happens when gif is not visible and then appears visible @@ -196,7 +196,7 @@ namespace dchat texture.generateMipmap(); sprite.setTexture(texture, true); } - target.draw(sprite); + target.draw(sprite, renderState); } bool Gif::isDataGif(const StringView &data) 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 #include #include #include @@ -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; } diff --git a/src/ResourceCache.cpp b/src/ResourceCache.cpp index 3f73189..4664bf0 100644 --- a/src/ResourceCache.cpp +++ b/src/ResourceCache.cpp @@ -7,6 +7,7 @@ namespace dchat { unordered_map fonts; unordered_map textures; + unordered_map shaders; const sf::Font* ResourceCache::getFont(const string &filepath) { @@ -47,4 +48,23 @@ namespace dchat textures[filepath] = texture; return texture; } + + sf::Shader* ResourceCache::getShader(const std::string &filepath, sf::Shader::Type shaderType) + { + auto it = shaders.find(filepath); + if(it != shaders.end()) + return it->second; + + sf::Shader *shader = new sf::Shader(); + if(!shader->loadFromFile(filepath, shaderType)) + { + delete shader; + string errMsg = "Failed to load shader: "; + errMsg += filepath; + throw FailedToLoadResourceException(errMsg); + } + + shaders[filepath] = shader; + return shader; + } } diff --git a/src/Text.cpp b/src/Text.cpp index be147db..9ea4847 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -2,6 +2,7 @@ #include "../include/Cache.hpp" #include "../include/Gif.hpp" #include "../include/WebPagePreview.hpp" +#include "../include/ColorScheme.hpp" #include #include @@ -27,7 +28,6 @@ namespace dchat plainText(false), editable(false), caretMoveDirection(CaretMoveDirection::NONE), - totalHeight(0.0f), caretIndex(0) { @@ -46,7 +46,6 @@ namespace dchat plainText(_plainText), editable(false), caretMoveDirection(CaretMoveDirection::NONE), - totalHeight(0.0f), lineSpacing(0.0f), caretIndex(0) { @@ -126,7 +125,7 @@ namespace dchat float Text::getHeight() const { - return totalHeight; + return boundingBox.height; } size_t stringSplitUrl(const StringViewUtf32 textElementStr, const sf::String &urlStr, size_t offset, std::vector &newTextElements) @@ -282,6 +281,8 @@ namespace dchat float hspace = font->getGlyph(' ', characterSize, false).advance; float vspace = font->getLineSpacing(characterSize); + boundingBox = sf::FloatRect(); + sf::Vector2f glyphPos; sf::Uint32 prevCodePoint = 0; size_t lastSpacingWordWrapIndex = -1; @@ -335,6 +336,7 @@ namespace dchat glyphPos.y += vspace + lineSpacing; } + boundingBox.width = std::max(boundingBox.width, glyphPos.x); continue; } @@ -451,7 +453,14 @@ namespace dchat glyphPos.y += floor(vspace * IMAGE_HEIGHT_SCALE) + lineSpacing; } } - totalHeight = glyphPos.y + vspace + lineSpacing; + + boundingBox.height = glyphPos.y + vspace + lineSpacing; + usize numVertices = vertices.getVertexCount(); + for(usize i = 0; i < numVertices; i += 4) + { + const sf::Vertex &bottomRight = vertices[i + 2]; + boundingBox.width = std::max(boundingBox.width, bottomRight.position.x); + } } void Text::updateCaret() @@ -616,7 +625,9 @@ namespace dchat void Text::processEvent(const sf::Event &event) { - if(!editable) return; + if(!editable || textElements.size() == 0) return; + + bool caretAtEnd = textElements[0].text.size == 0 || caretIndex == textElements[0].text.size; if(event.type == sf::Event::KeyPressed) { @@ -625,7 +636,7 @@ namespace dchat --caretIndex; dirtyCaret = true; } - else if(event.key.code == sf::Keyboard::Right && !isCaretAtEnd()) + else if(event.key.code == sf::Keyboard::Right && !caretAtEnd) { ++caretIndex; dirtyCaret = true; @@ -638,7 +649,7 @@ namespace dchat --caretIndex; dirtyCaret = true; } - else if(event.key.code == sf::Keyboard::Delete && !isCaretAtEnd()) + else if(event.key.code == sf::Keyboard::Delete && !caretAtEnd) { auto strBefore = str.substring(0, caretIndex); auto strAfter = str.substring(caretIndex + 1); @@ -666,7 +677,7 @@ namespace dchat if(event.text.unicode == 8 || event.text.unicode == 127) // backspace, del return; - if(isCaretAtEnd()) + if(caretAtEnd) str += event.text.unicode; else { @@ -715,7 +726,15 @@ namespace dchat //sf::FloatRect textRect(pos.x, pos.y, maxWidth, ) //colRect.contains() //if(pos.x + maxWidth <= 0.0f || pos.x >= maxWidth || pos.y + totalHeight <= 0.0f || pos.y >= target.getSize().y) return; - if(pos.y + totalHeight <= 0.0f || pos.y >= target.getSize().y) return; + if(pos.y + getHeight() <= 0.0f || pos.y >= target.getSize().y) return; + + if(editable) + { + sf::RectangleShape editBox(sf::Vector2f(std::max(maxWidth, boundingBox.width), boundingBox.height)); + editBox.setPosition(pos.x, pos.y - floor(vspace)); + editBox.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(10, 10, 10)); + target.draw(editBox); + } states.transform.translate(pos); states.texture = &font->getTexture(characterSize); diff --git a/src/UsersSidePanel.cpp b/src/UsersSidePanel.cpp index 9c04062..672dffa 100644 --- a/src/UsersSidePanel.cpp +++ b/src/UsersSidePanel.cpp @@ -23,14 +23,23 @@ namespace dchat sf::RectangleShape rect(sf::Vector2f(getWidth(), windowSize.y - ChannelTopPanel::getHeight())); rect.setFillColor(ColorScheme::getPanelColor()); rect.setPosition(windowSize.x - getWidth(), posY); - window.draw(rect); - posY += 10.0f; + //window.draw(rect); Channel *currentChannel = Channel::getCurrent(); if(!currentChannel) return; const sf::Font *font = ResourceCache::getFont("fonts/Roboto-Regular.ttf"); sf::Vector2f position(rect.getPosition().x + 10.0f, posY); + + // TODO: Remove this shit + sf::String str = "Online - "; + str += to_string(currentChannel->getUsers().size()); + sf::Text text(str, *font, FONT_SIZE * Settings::getScaling() * 1.25f); + text.setPosition(position); + text.setFillColor(ColorScheme::getTextRegularColor()); + window.draw(text); + position.y += floor(font->getLineSpacing(text.getCharacterSize())); + for(User *user : currentChannel->getUsers()) { // TODO: Remove this shit -- cgit v1.2.3