Fix smooth scrolling when ChannelView is full (#4501)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
Andrew Opalach
2023-06-18 12:09:11 +00:00
committed by GitHub
parent 4b40b9a310
commit 0e60ca10d0
6 changed files with 152 additions and 140 deletions
+38 -55
View File
@@ -328,8 +328,10 @@ void ChannelView::updatePauses()
this->pauseEnd_ = boost::none;
this->pauseTimer_.stop();
this->scrollBar_->offset(this->pauseScrollOffset_);
this->pauseScrollOffset_ = 0;
this->scrollBar_->offsetMaximum(this->pauseScrollMaximumOffset_);
this->scrollBar_->offsetMinimum(this->pauseScrollMinimumOffset_);
this->pauseScrollMinimumOffset_ = 0;
this->pauseScrollMaximumOffset_ = 0;
this->queueLayout();
}
@@ -453,7 +455,7 @@ void ChannelView::performLayout(bool causedByScrollbar)
void ChannelView::layoutVisibleMessages(
const LimitedQueueSnapshot<MessageLayoutPtr> &messages)
{
const auto start = size_t(this->scrollBar_->getCurrentValue());
const auto start = size_t(this->scrollBar_->getRelativeCurrentValue());
const auto layoutWidth = this->getLayoutWidth();
const auto flags = this->getFlags();
auto redrawRequired = false;
@@ -461,7 +463,7 @@ void ChannelView::layoutVisibleMessages(
if (messages.size() > start)
{
auto y = int(-(messages[start]->getHeight() *
(fmod(this->scrollBar_->getCurrentValue(), 1))));
(fmod(this->scrollBar_->getRelativeCurrentValue(), 1))));
for (auto i = start; i < messages.size() && y <= this->height(); i++)
{
@@ -521,21 +523,17 @@ void ChannelView::updateScrollbar(
if (!showScrollbar && !causedByScrollbar)
{
this->scrollBar_->setDesiredValue(0);
this->scrollBar_->scrollToTop();
}
this->showScrollBar_ = showScrollbar;
this->scrollBar_->setMaximum(messages.size());
// If we were showing the latest messages and the scrollbar now wants to be
// rendered, scroll to bottom
if (this->enableScrollingToBottom_ && this->showingLatestMessages_ &&
showScrollbar)
showScrollbar && !causedByScrollbar)
{
this->scrollBar_->scrollToBottom(
// this->messageWasAdded &&
getSettings()->enableSmoothScrollingNewMessages.getValue());
this->messageWasAdded_ = false;
}
}
@@ -544,6 +542,9 @@ void ChannelView::clearMessages()
// Clear all stored messages in this chat widget
this->messages_.clear();
this->scrollBar_->clearHighlights();
this->scrollBar_->resetMaximum();
this->scrollBar_->setMaximum(0);
this->scrollBar_->setMinimum(0);
this->queueLayout();
this->lastMessageHasAlternateBackground_ = false;
@@ -750,12 +751,6 @@ void ChannelView::setChannel(ChannelPtr underlyingChannel)
this->messageAddedAtStart(messages);
});
// on message removed
this->channelConnections_.managedConnect(
this->channel_->messageRemovedFromStart, [this](MessagePtr &message) {
this->messageRemoveFromStart(message);
});
// on message replaced
this->channelConnections_.managedConnect(
this->channel_->messageReplaced,
@@ -771,6 +766,8 @@ void ChannelView::setChannel(ChannelPtr underlyingChannel)
auto snapshot = underlyingChannel->getMessageSnapshot();
this->scrollBar_->setMaximum(qreal(snapshot.size()));
for (const auto &msg : snapshot)
{
auto messageLayout = std::make_shared<MessageLayout>(msg);
@@ -881,31 +878,26 @@ void ChannelView::messageAppended(MessagePtr &message,
this->lastMessageHasAlternateBackground_ =
!this->lastMessageHasAlternateBackground_;
if (!this->scrollBar_->isAtBottom() &&
this->scrollBar_->getCurrentValueAnimation().state() ==
QPropertyAnimation::Running)
if (this->paused())
{
QEventLoop loop;
connect(&this->scrollBar_->getCurrentValueAnimation(),
&QAbstractAnimation::stateChanged, &loop, &QEventLoop::quit);
loop.exec();
this->pauseScrollMaximumOffset_++;
}
else
{
this->scrollBar_->offsetMaximum(1);
}
if (this->messages_.pushBack(messageRef))
{
if (this->paused())
{
if (!this->scrollBar_->isAtBottom())
this->pauseScrollOffset_--;
this->pauseScrollMinimumOffset_++;
this->pauseSelectionOffset_++;
}
else
{
if (this->scrollBar_->isAtBottom())
this->scrollBar_->scrollToBottom();
else
this->scrollBar_->offset(-1);
this->scrollBar_->offsetMinimum(1);
this->selection_.shiftMessageIndex(1);
}
}
@@ -931,7 +923,6 @@ void ChannelView::messageAppended(MessagePtr &message,
this->scrollBar_->addHighlight(message->getScrollBarHighlight());
}
this->messageWasAdded_ = true;
this->queueLayout();
}
@@ -956,12 +947,14 @@ void ChannelView::messageAddedAtStart(std::vector<MessagePtr> &messages)
}
/// Add the messages at the start
if (this->messages_.pushFront(messageRefs).size() > 0)
auto addedMessages = this->messages_.pushFront(messageRefs);
if (!addedMessages.empty())
{
if (this->scrollBar_->isAtBottom())
this->scrollBar_->scrollToBottom();
else
this->scrollBar_->offset(qreal(messages.size()));
this->scrollBar_->offset(qreal(addedMessages.size()));
this->scrollBar_->offsetMaximum(qreal(addedMessages.size()));
}
if (this->showScrollbarHighlights())
@@ -976,21 +969,6 @@ void ChannelView::messageAddedAtStart(std::vector<MessagePtr> &messages)
this->scrollBar_->addHighlightsAtStart(highlights);
}
this->messageWasAdded_ = true;
this->queueLayout();
}
void ChannelView::messageRemoveFromStart(MessagePtr &message)
{
if (this->paused())
{
this->pauseSelectionOffset_ += 1;
}
else
{
this->selection_.shiftMessageIndex(1);
}
this->queueLayout();
}
@@ -1024,6 +1002,9 @@ void ChannelView::messagesUpdated()
this->messages_.clear();
this->scrollBar_->clearHighlights();
this->scrollBar_->resetMaximum();
this->scrollBar_->setMaximum(qreal(snapshot.size()));
this->scrollBar_->setMinimum(0);
this->lastMessageHasAlternateBackground_ = false;
this->lastMessageHasAlternateBackgroundReverse_ = true;
@@ -1227,7 +1208,8 @@ void ChannelView::scrollToMessageLayout(MessageLayout *layout,
if (this->showScrollBar_)
{
this->getScrollBar().setDesiredValue(messageIdx);
this->getScrollBar().setDesiredValue(this->scrollBar_->getMinimum() +
qreal(messageIdx));
}
}
@@ -1258,7 +1240,7 @@ void ChannelView::drawMessages(QPainter &painter)
{
auto &messagesSnapshot = this->getMessagesSnapshot();
size_t start = size_t(this->scrollBar_->getCurrentValue());
const auto start = size_t(this->scrollBar_->getRelativeCurrentValue());
if (start >= messagesSnapshot.size())
{
@@ -1266,7 +1248,7 @@ void ChannelView::drawMessages(QPainter &painter)
}
int y = int(-(messagesSnapshot[start].get()->getHeight() *
(fmod(this->scrollBar_->getCurrentValue(), 1))));
(fmod(this->scrollBar_->getRelativeCurrentValue(), 1))));
MessageLayout *end = nullptr;
bool windowFocused = this->window() == QApplication::activeWindow();
@@ -1368,7 +1350,8 @@ void ChannelView::wheelEvent(QWheelEvent *event)
auto &snapshot = this->getMessagesSnapshot();
int snapshotLength = int(snapshot.size());
int i = std::min<int>(int(desired), snapshotLength);
int i = std::min<int>(int(desired - this->scrollBar_->getMinimum()),
snapshotLength - 1);
if (delta > 0)
{
@@ -2779,7 +2762,7 @@ bool ChannelView::tryGetMessageAt(QPoint p,
{
auto &messagesSnapshot = this->getMessagesSnapshot();
size_t start = this->scrollBar_->getCurrentValue();
const auto start = size_t(this->scrollBar_->getRelativeCurrentValue());
if (start >= messagesSnapshot.size())
{
@@ -2787,7 +2770,7 @@ bool ChannelView::tryGetMessageAt(QPoint p,
}
int y = -(messagesSnapshot[start]->getHeight() *
(fmod(this->scrollBar_->getCurrentValue(), 1)));
(fmod(this->scrollBar_->getRelativeCurrentValue(), 1)));
for (size_t i = start; i < messagesSnapshot.size(); ++i)
{