mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
optimizations and tweaks
This commit is contained in:
parent
783caf932c
commit
53ba982203
8
qtox.pro
8
qtox.pro
@ -193,7 +193,9 @@ HEADERS += src/widget/form/addfriendform.h \
|
||||
src/widget/form/settings/advancedform.h \
|
||||
src/audio.h \
|
||||
src/chatlog/content/notificationicon.h \
|
||||
src/chatlog/content/timestamp.h
|
||||
src/chatlog/content/timestamp.h \
|
||||
src/chatlog/documentcache.h \
|
||||
src/chatlog/pixmapcache.h
|
||||
|
||||
SOURCES += \
|
||||
src/widget/form/addfriendform.cpp \
|
||||
@ -264,7 +266,9 @@ SOURCES += \
|
||||
src/widget/form/settings/advancedform.cpp \
|
||||
src/audio.cpp \
|
||||
src/chatlog/content/notificationicon.cpp \
|
||||
src/chatlog/content/timestamp.cpp
|
||||
src/chatlog/content/timestamp.cpp \
|
||||
src/chatlog/documentcache.cpp \
|
||||
src/chatlog/pixmapcache.cpp
|
||||
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
HEADERS += src/audiofilterer.h
|
||||
|
@ -47,18 +47,18 @@ ChatLog::ChatLog(QWidget* parent)
|
||||
|
||||
// Cfg.
|
||||
setInteractive(true);
|
||||
setAcceptDrops(false);
|
||||
setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setDragMode(QGraphicsView::NoDrag);
|
||||
setViewportUpdateMode(BoundingRectViewportUpdate);
|
||||
setAcceptDrops(false);
|
||||
setViewportUpdateMode(MinimalViewportUpdate);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
setBackgroundBrush(QBrush(Qt::white, Qt::SolidPattern));
|
||||
|
||||
// The selection rect for multi-line selection
|
||||
const QColor selGraphColor = QColor(166,225,255);
|
||||
selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor);
|
||||
selGraphItem->setZValue(-10.0); //behind all items
|
||||
selGraphItem->setZValue(-1.0); // behind all other items
|
||||
|
||||
// copy action (ie. Ctrl+C)
|
||||
QAction* copyAction = new QAction(this);
|
||||
@ -79,7 +79,7 @@ ChatLog::ChatLog(QWidget* parent)
|
||||
// This timer is used to scroll the view while the user is
|
||||
// moving the mouse past the top/bottom edge of the widget while selecting.
|
||||
selectionTimer = new QTimer(this);
|
||||
selectionTimer->setInterval(1000/60);
|
||||
selectionTimer->setInterval(1000/30);
|
||||
selectionTimer->setSingleShot(false);
|
||||
selectionTimer->start();
|
||||
connect(selectionTimer, &QTimer::timeout, this, &ChatLog::onSelectionTimerTimeout);
|
||||
@ -575,7 +575,7 @@ void ChatLog::checkVisibility()
|
||||
auto lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), ChatLine::lessThanBSRectBottom);
|
||||
|
||||
// find last visible line
|
||||
auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), ChatLine::lessThanBSRectTop);
|
||||
auto upperBound = std::lower_bound(lowerBound, lines.cend(), getVisibleRect().bottom(), ChatLine::lessThanBSRectTop);
|
||||
|
||||
// set visibilty
|
||||
QList<ChatLine::Ptr> newVisibleLines;
|
||||
@ -624,7 +624,8 @@ void ChatLog::updateMultiSelectionRect()
|
||||
selBBox = selBBox.united(lines[selFirstRow]->sceneBoundingRect());
|
||||
selBBox = selBBox.united(lines[selLastRow]->sceneBoundingRect());
|
||||
|
||||
scene->invalidate(selGraphItem->sceneBoundingRect());
|
||||
if(selGraphItem->rect() != selBBox)
|
||||
scene->invalidate(selGraphItem->rect());
|
||||
|
||||
selGraphItem->setRect(selBBox);
|
||||
selGraphItem->show();
|
||||
|
@ -104,7 +104,7 @@ ChatMessage::Ptr ChatMessage::createTypingNotification()
|
||||
ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage);
|
||||
|
||||
// Note: "[user]..." is just a placeholder. The actual text is set in ChatForm::setFriendTyping()
|
||||
msg->addColumn(new NotificationIcon(QSizeF(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
||||
msg->addColumn(new NotificationIcon(QSize(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right));
|
||||
msg->addColumn(new Text("[user]...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left));
|
||||
|
||||
return msg;
|
||||
|
@ -15,13 +15,14 @@
|
||||
*/
|
||||
|
||||
#include "image.h"
|
||||
#include "../pixmapcache.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
Image::Image(QSize Size, const QString& filename)
|
||||
: size(Size)
|
||||
{
|
||||
icon.addFile(filename);
|
||||
pmap = PixmapCache::getInstance().get(filename, size);
|
||||
}
|
||||
|
||||
QRectF Image::boundingRect() const
|
||||
@ -38,7 +39,7 @@ void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWi
|
||||
{
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->translate(-size.width() / 2.0, -size.height() / 2.0);
|
||||
painter->drawPixmap(0, 0, icon.pixmap(size));
|
||||
painter->drawPixmap(0, 0, pmap);
|
||||
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "../chatlinecontent.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
|
||||
class Image : public ChatLineContent
|
||||
{
|
||||
@ -33,7 +33,7 @@ public:
|
||||
|
||||
private:
|
||||
QSize size;
|
||||
QIcon icon;
|
||||
QPixmap pmap;
|
||||
|
||||
};
|
||||
|
||||
|
@ -15,17 +15,19 @@
|
||||
*/
|
||||
|
||||
#include "notificationicon.h"
|
||||
#include "../pixmapcache.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
NotificationIcon::NotificationIcon(QSizeF Size)
|
||||
NotificationIcon::NotificationIcon(QSize Size)
|
||||
: size(Size)
|
||||
{
|
||||
icon.addFile(":/ui/chatArea/typing.svg");
|
||||
pmap = PixmapCache::getInstance().get(":/ui/chatArea/typing.svg", size);
|
||||
|
||||
updateTimer = new QTimer(this);
|
||||
updateTimer->setInterval(1000/60);
|
||||
updateTimer->setInterval(1000/30);
|
||||
updateTimer->setSingleShot(false);
|
||||
|
||||
updateTimer->start();
|
||||
@ -44,7 +46,7 @@ void NotificationIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
||||
painter->translate(-size.width() / 2.0, -size.height() / 2.0);
|
||||
|
||||
painter->fillRect(QRect(0, 0, size.width(), size.height()), grad);
|
||||
painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize() * painter->device()->devicePixelRatio()));
|
||||
painter->drawPixmap(0, 0, size.width(), size.height(), pmap);
|
||||
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
@ -62,7 +64,7 @@ qreal NotificationIcon::getAscent() const
|
||||
|
||||
void NotificationIcon::updateGradient()
|
||||
{
|
||||
alpha += 0.005;
|
||||
alpha += 0.01;
|
||||
|
||||
if(alpha + dotWidth >= 1.0)
|
||||
alpha = 0.0;
|
||||
@ -70,9 +72,10 @@ void NotificationIcon::updateGradient()
|
||||
grad = QLinearGradient(QPointF(-0.5*size.width(),0), QPointF(3.0/2.0*size.width(),0));
|
||||
grad.setColorAt(0, Qt::lightGray);
|
||||
grad.setColorAt(qMax(0.0, alpha - dotWidth), Qt::lightGray);
|
||||
grad.setColorAt(alpha, Qt::darkGray);
|
||||
grad.setColorAt(alpha, Qt::black);
|
||||
grad.setColorAt(qMin(1.0, alpha + dotWidth), Qt::lightGray);
|
||||
grad.setColorAt(1, Qt::lightGray);
|
||||
|
||||
update();
|
||||
if(scene())
|
||||
scene()->invalidate(sceneBoundingRect());
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "../chatlinecontent.h"
|
||||
|
||||
#include <QLinearGradient>
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
|
||||
class QTimer;
|
||||
|
||||
@ -28,7 +28,7 @@ class NotificationIcon : public QObject, public ChatLineContent
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NotificationIcon(QSizeF size);
|
||||
NotificationIcon(QSize size);
|
||||
|
||||
virtual QRectF boundingRect() const override;
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
@ -39,8 +39,8 @@ private slots:
|
||||
void updateGradient();
|
||||
|
||||
private:
|
||||
QSizeF size;
|
||||
QIcon icon;
|
||||
QSize size;
|
||||
QPixmap pmap;
|
||||
QLinearGradient grad;
|
||||
QTimer* updateTimer = nullptr;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "spinner.h"
|
||||
#include "../pixmapcache.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGraphicsScene>
|
||||
@ -24,9 +25,9 @@ Spinner::Spinner(const QString &img, QSize Size, qreal speed)
|
||||
: size(Size)
|
||||
, rotSpeed(speed)
|
||||
{
|
||||
icon.addFile(img);
|
||||
pmap = PixmapCache::getInstance().get(img, size);
|
||||
|
||||
timer.setInterval(33); // 30Hz
|
||||
timer.setInterval(1000/30); // 30Hz
|
||||
timer.setSingleShot(false);
|
||||
|
||||
QObject::connect(&timer, &QTimer::timeout, this, &Spinner::timeout);
|
||||
@ -47,7 +48,7 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q
|
||||
painter->translate(-size.width() / 2.0, -size.height() / 2.0);
|
||||
painter->setTransform(rotMat, true);
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->drawPixmap(0, 0, icon.pixmap(size));
|
||||
painter->drawPixmap(0, 0, pmap);
|
||||
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
|
||||
class Spinner : public QObject, public ChatLineContent
|
||||
{
|
||||
@ -40,7 +40,7 @@ private slots:
|
||||
|
||||
private:
|
||||
QSize size;
|
||||
QIcon icon;
|
||||
QPixmap pmap;
|
||||
qreal rot = 0.0;
|
||||
qreal rotSpeed;
|
||||
QTimer timer;
|
||||
|
@ -15,8 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "text.h"
|
||||
|
||||
#include "../customtextdocument.h"
|
||||
#include "../documentcache.h"
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QPainter>
|
||||
@ -40,7 +39,8 @@ Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwTe
|
||||
|
||||
Text::~Text()
|
||||
{
|
||||
delete doc;
|
||||
if(doc)
|
||||
DocumentCache::getInstance().push(doc);
|
||||
}
|
||||
|
||||
void Text::setText(const QString& txt)
|
||||
@ -212,7 +212,7 @@ void Text::regenerate()
|
||||
{
|
||||
if(!doc)
|
||||
{
|
||||
doc = new CustomTextDocument();
|
||||
doc = DocumentCache::getInstance().pop();
|
||||
doc->setDefaultFont(defFont);
|
||||
dirty = true;
|
||||
}
|
||||
@ -231,24 +231,24 @@ void Text::regenerate()
|
||||
doc->setPlainText(elidedText);
|
||||
}
|
||||
|
||||
// width & layout
|
||||
doc->setTextWidth(width);
|
||||
doc->documentLayout()->update();
|
||||
|
||||
// update ascent
|
||||
if(doc->firstBlock().layout()->lineCount() > 0)
|
||||
ascent = doc->firstBlock().layout()->lineAt(0).ascent();
|
||||
|
||||
// let the scene know about our change in size
|
||||
if(size != idealSize())
|
||||
prepareGeometryChange();
|
||||
|
||||
// get the new width and height
|
||||
size = idealSize();
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
// width & layout
|
||||
doc->setTextWidth(width);
|
||||
doc->documentLayout()->update();
|
||||
|
||||
// update ascent
|
||||
if(doc->firstBlock().layout()->lineCount() > 0)
|
||||
ascent = doc->firstBlock().layout()->lineAt(0).ascent();
|
||||
|
||||
// let the scene know about our change in size
|
||||
if(size != idealSize())
|
||||
prepareGeometryChange();
|
||||
|
||||
// get the new width and height
|
||||
size = idealSize();
|
||||
|
||||
// if we are not visible -> free mem
|
||||
if(!keepInMemory)
|
||||
freeResources();
|
||||
@ -256,7 +256,7 @@ void Text::regenerate()
|
||||
|
||||
void Text::freeResources()
|
||||
{
|
||||
delete doc;
|
||||
DocumentCache::getInstance().push(doc);
|
||||
doc = nullptr;
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,9 @@
|
||||
|
||||
#include "../chatlinecontent.h"
|
||||
|
||||
#include <QTextDocument>
|
||||
#include <QTextCursor>
|
||||
#include <QFont>
|
||||
|
||||
class CustomTextDocument;
|
||||
class QTextDocument;
|
||||
|
||||
class Text : public ChatLineContent
|
||||
{
|
||||
@ -67,7 +66,7 @@ protected:
|
||||
QString extractSanitizedText(int from, int to) const;
|
||||
|
||||
private:
|
||||
CustomTextDocument* doc = nullptr;
|
||||
QTextDocument* doc = nullptr;
|
||||
QString text;
|
||||
QString rawText;
|
||||
QString elidedText;
|
||||
|
44
src/chatlog/documentcache.cpp
Normal file
44
src/chatlog/documentcache.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (C) 2015 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "documentcache.h"
|
||||
#include "customtextdocument.h"
|
||||
|
||||
DocumentCache DocumentCache::instance;
|
||||
|
||||
DocumentCache::~DocumentCache()
|
||||
{
|
||||
while(!documents.isEmpty())
|
||||
delete documents.pop();
|
||||
}
|
||||
|
||||
QTextDocument* DocumentCache::pop()
|
||||
{
|
||||
if(documents.empty())
|
||||
documents.push(new CustomTextDocument);
|
||||
|
||||
return documents.pop();
|
||||
}
|
||||
|
||||
void DocumentCache::push(QTextDocument *doc)
|
||||
{
|
||||
documents.push(doc);
|
||||
}
|
||||
|
||||
DocumentCache &DocumentCache::getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
43
src/chatlog/documentcache.h
Normal file
43
src/chatlog/documentcache.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (C) 2015 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#ifndef DOCUMENTCACHE_H
|
||||
#define DOCUMENTCACHE_H
|
||||
|
||||
#include <QStack>
|
||||
|
||||
class QTextDocument;
|
||||
|
||||
class DocumentCache
|
||||
{
|
||||
public:
|
||||
~DocumentCache();
|
||||
static DocumentCache& getInstance();
|
||||
|
||||
QTextDocument* pop();
|
||||
void push(QTextDocument* doc);
|
||||
|
||||
protected:
|
||||
DocumentCache() {}
|
||||
DocumentCache(DocumentCache&) = delete;
|
||||
DocumentCache& operator=(const DocumentCache&) = delete;
|
||||
|
||||
private:
|
||||
QStack<QTextDocument*> documents;
|
||||
static DocumentCache instance;
|
||||
};
|
||||
|
||||
#endif // DOCUMENTCACHE_H
|
41
src/chatlog/pixmapcache.cpp
Normal file
41
src/chatlog/pixmapcache.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (C) 2015 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "pixmapcache.h"
|
||||
|
||||
PixmapCache PixmapCache::instance;
|
||||
|
||||
QPixmap PixmapCache::get(const QString &filename, QSize size)
|
||||
{
|
||||
auto itr = cache.find(filename);
|
||||
|
||||
if(itr == cache.end())
|
||||
{
|
||||
QIcon icon;
|
||||
icon.addFile(filename);
|
||||
|
||||
cache.insert(filename, icon);
|
||||
return icon.pixmap(size);
|
||||
}
|
||||
|
||||
return itr.value().pixmap(size);
|
||||
}
|
||||
|
||||
PixmapCache &PixmapCache::getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
40
src/chatlog/pixmapcache.h
Normal file
40
src/chatlog/pixmapcache.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (C) 2015 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#ifndef ICONCACHE_H
|
||||
#define ICONCACHE_H
|
||||
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
#include <QHash>
|
||||
|
||||
class PixmapCache
|
||||
{
|
||||
public:
|
||||
QPixmap get(const QString& filename, QSize size);
|
||||
static PixmapCache& getInstance();
|
||||
|
||||
protected:
|
||||
PixmapCache() {}
|
||||
PixmapCache(PixmapCache&) = delete;
|
||||
PixmapCache& operator=(const PixmapCache&) = delete;
|
||||
|
||||
private:
|
||||
QHash<QString, QIcon> cache;
|
||||
static PixmapCache instance;
|
||||
};
|
||||
|
||||
#endif // ICONCACHE_H
|
Loading…
x
Reference in New Issue
Block a user