diff options
Diffstat (limited to 'src/MessageBoard.cpp')
-rw-r--r-- | src/MessageBoard.cpp | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/src/MessageBoard.cpp b/src/MessageBoard.cpp index 8e1525f..2e92d7f 100644 --- a/src/MessageBoard.cpp +++ b/src/MessageBoard.cpp @@ -46,7 +46,9 @@ namespace dchat scroll(0.0), scrollSpeed(0.0), totalHeight(0.0), - scrollToBottom(false) + scrollToBottom(false), + visibleMessageStartIndex(-1), + visibleMessageEndIndex(-1) { } @@ -81,8 +83,8 @@ namespace dchat { lock_guard<mutex> lock(messageProcessMutex); messages.insert(messages.begin() + findPositionToInsertMessageByTimestamp(message), message); - if(!id.isEmpty()) - messageIdMap[id] = message; + message->id = id; + messageIdMap[id] = message; dirty = true; scrollToBottom = true; } @@ -102,6 +104,7 @@ namespace dchat } } + // TODO: Instead of deleting message, cover it with black rectangle for(usize i = 0; i < messages.size(); ++i) { Message *message = messages[i]; @@ -137,6 +140,9 @@ namespace dchat sf::Vector2<double> position(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling(), ChannelTopPanel::getHeight() + PADDING_TOP); double startHeight = position.y; position.y += scroll; + + visibleMessageStartIndex = -1; + visibleMessageEndIndex = -1; usize numMessages = messages.size(); for(usize i = 0; i < numMessages; ++i) { @@ -156,11 +162,14 @@ namespace dchat mergeTextWithNext = nextMessage->user == message->user && (nextMessage->timestampSeconds == 0 || nextMessage->timestampSeconds - message->timestampSeconds <= MERGE_TEXT_TIMESTAMP_DIFF_SEC); } + bool visible = false; + if(!mergeTextWithPrev) { position.y += (MESSAGE_PADDING_TOP * Settings::getScaling()); if(position.y + usernameTextHeight > 0.0f && position.y < backgroundPos.y + backgroundSize.y) { + visible = true; 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))); @@ -219,7 +228,9 @@ namespace dchat 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); + bool textDrawn = message->text.draw(window, cache); + if(!visible) + visible = textDrawn; position.y += message->text.getHeight(); if(!mergeTextWithNext) { @@ -227,12 +238,20 @@ namespace dchat if(position.y + LINE_HEIGHT > 0.0f && position.y < backgroundPos.y + backgroundSize.y && i + 1 != numMessages) { + visible = true; 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; + + if(visible) + { + if(visibleMessageStartIndex == -1) + visibleMessageStartIndex = i; + visibleMessageEndIndex = i; + } } totalHeight = (position.y - scroll) - startHeight; } @@ -294,40 +313,42 @@ namespace dchat totalHeight = (position.y - scroll) - startHeight; } - void MessageBoard::processEvent(const sf::Event &event) + void MessageBoard::processEvent(const sf::Event &event, Cache &cache) { lock_guard<mutex> lock(messageProcessMutex); - for(Message *message : messages) - { - message->text.processEvent(event); - } OnlineLocalUser *onlineLocalUser = nullptr; if(channel->getLocalUser()->type == User::Type::ONLINE_LOCAL_USER) onlineLocalUser = static_cast<OnlineLocalUser*>(channel->getLocalUser()); + bool openContextMenu = false; if(onlineLocalUser && event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Button::Right) + openContextMenu = true; + + if(visibleMessageStartIndex != -1) { - for(auto it : messageIdMap) + //printf("visibleMessageStartIndex: %u, visibleMessageEndIndex: %u\n", visibleMessageStartIndex, visibleMessageEndIndex); + for(usize i = visibleMessageStartIndex; i <= visibleMessageEndIndex; ++i) { - it.second->text.processEvent(event); - auto textPos = it.second->text.getPosition(); - if(it.second->user == channel->getLocalUser() && event.mouseButton.x >= textPos.x && event.mouseButton.x <= textPos.x + it.second->text.getMaxWidth() && event.mouseButton.y >= textPos.y && event.mouseButton.y <= textPos.y + it.second->text.getHeight()) + Message *message = messages[i]; + message->text.processEvent(event, cache); + + auto textPos = message->text.getPosition(); + if(openContextMenu && message->user == channel->getLocalUser() && event.mouseButton.x >= textPos.x && event.mouseButton.x <= textPos.x + message->text.getMaxWidth() && event.mouseButton.y >= textPos.y && event.mouseButton.y <= textPos.y + message->text.getHeight()) { auto contextMenu = GlobalContextMenu::getEditMessageContextMenu(); contextMenu->setPosition(sf::Vector2f(event.mouseButton.x, event.mouseButton.y)); contextMenu->setVisible(true); - GlobalContextMenu::setClickDeleteMessageCallbackFunc([this, it, onlineLocalUser](ContextMenuItem *menuItem) + GlobalContextMenu::setClickDeleteMessageCallbackFunc([this, message, onlineLocalUser](ContextMenuItem *menuItem) { - channel->deleteMessage(it.first, onlineLocalUser->getPublicKey()); + channel->deleteMessage(message->id, onlineLocalUser->getPublicKey()); GlobalContextMenu::setClickDeleteMessageCallbackFunc(nullptr); }); - return; } } - GlobalContextMenu::setClickDeleteMessageCallbackFunc(nullptr); } - else if(event.type == sf::Event::MouseWheelScrolled && event.mouseWheelScroll.wheel == sf::Mouse::Wheel::VerticalWheel) + + if(event.type == sf::Event::MouseWheelScrolled && event.mouseWheelScroll.wheel == sf::Mouse::Wheel::VerticalWheel) { scrollSpeed += (event.mouseWheelScroll.delta * 5.0); if(scrollSpeed > SCROLL_MAX_SPEED) |