summary refs log tree commit diff
path: root/src/timeline/TimelineItem.cpp
diff options
context:
space:
mode:
authorredsky17 <joedonofry@gmail.com>2019-02-08 01:58:00 +0000
committerredsky17 <joedonofry@gmail.com>2019-02-08 01:58:00 +0000
commit13663ad5f894f035a47efd5704e84f07d68b3df2 (patch)
tree9ae1c461e5b93ab7c110b5880b9f38003349cde3 /src/timeline/TimelineItem.cpp
parentMerge branch 'ui-enhancements' (diff)
downloadnheko-13663ad5f894f035a47efd5704e84f07d68b3df2.tar.xz
Improve color generation performance
Colors are generated asynchronously now and the TimelineItem is
updated when the color generation finishes.  This allows the UI
to stay responsive while new colors are being generated.
Diffstat (limited to 'src/timeline/TimelineItem.cpp')
-rw-r--r--src/timeline/TimelineItem.cpp64
1 files changed, 46 insertions, 18 deletions
diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp

index 1c90eade..d23dbf49 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp
@@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <functional> #include <QContextMenuEvent> #include <QDesktopServices> @@ -197,6 +198,12 @@ TimelineItem::init() connect(markAsRead_, &QAction::triggered, this, &TimelineItem::sendReadReceipt); connect(viewRawMessage_, &QAction::triggered, this, &TimelineItem::openRawMessageViewer); + colorGenerating_ = new QFutureWatcher<QString>(this); + connect(colorGenerating_, + &QFutureWatcher<QString>::finished, + this, + &TimelineItem::finishedGeneratingColor); + topLayout_ = new QHBoxLayout(this); mainLayout_ = new QVBoxLayout; messageLayout_ = new QHBoxLayout; @@ -557,6 +564,12 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Text> adjustMessageLayout(); } +TimelineItem::~TimelineItem() +{ + colorGenerating_->cancel(); + colorGenerating_->waitForFinished(); +} + void TimelineItem::markSent() { @@ -607,16 +620,39 @@ TimelineItem::generateBody(const QString &body) void TimelineItem::refreshAuthorColor() { + // Cancel and wait if we are already generating the color. + if (colorGenerating_->isRunning()) { + colorGenerating_->cancel(); + colorGenerating_->waitForFinished(); + } if (userName_) { + // generate user's unique color. + std::function<QString()> generate = [this]() { + QString userColor = utils::generateContrastingHexColor( + userName_->toolTip(), backgroundColor().name()); + return userColor; + }; + QString userColor = Cache::userColor(userName_->toolTip()); + + // If the color is empty, then generate it asynchronously if (userColor.isEmpty()) { - // This attempts to refresh this item since it's not drawn - // which allows us to get the background color accurately. - qApp->style()->polish(this); - // generate user's unique color. - auto backCol = backgroundColor().name(); - userColor = - utils::generateContrastingHexColor(userName_->toolTip(), backCol); + colorGenerating_->setFuture(QtConcurrent::run(generate)); + } else { + userName_->setStyleSheet("QLabel { color : " + userColor + "; }"); + } + } +} + +void +TimelineItem::finishedGeneratingColor() +{ + nhlog::ui()->debug("finishedGeneratingColor for: {}", userName_->toolTip().toStdString()); + QString userColor = colorGenerating_->result(); + + if (!userColor.isEmpty()) { + // another TimelineItem might have inserted in the meantime. + if (Cache::userColor(userName_->toolTip()).isEmpty()) { Cache::insertUserColor(userName_->toolTip(), userColor); } userName_->setStyleSheet("QLabel { color : " + userColor + "; }"); @@ -656,17 +692,9 @@ TimelineItem::generateUserName(const QString &user_id, const QString &displaynam userName_->setAlignment(Qt::AlignLeft | Qt::AlignTop); userName_->setFixedWidth(QFontMetrics(userName_->font()).width(userName_->text())); - // TimelineItem isn't displayed. This forces the QSS to get - // loaded. - QString userColor = Cache::userColor(user_id); - if (userColor.isEmpty()) { - qApp->style()->polish(this); - // generate user's unique color. - auto backCol = backgroundColor().name(); - userColor = utils::generateContrastingHexColor(user_id, backCol); - Cache::insertUserColor(user_id, userColor); - } - userName_->setStyleSheet("QLabel { color : " + userColor + "; }"); + // Set the user color asynchronously if it hasn't been generated yet, + // otherwise this will just set it. + refreshAuthorColor(); auto filter = new UserProfileFilter(user_id, userName_); userName_->installEventFilter(filter);